21. 合并两个有序链表
同样是一道简单题,逻辑思路简单清晰。我原本是不愿意记录的。但是写着写着发现了新的东西,于是就记录了一下。
平时在写这题的时候,最后情况下会这样做:
if(l1!=null) pre.next=l1;
if(l2!=null) pre.next=l2;
但今天写着写着,这实际上完全可以变成一行,更清晰一点:
pre.next = l1==null? l2:l1;
于是就记录下来了,同时,在使用头节点来进行链表链接时候,实际上是不必给每一次的pre.next设置成null的,但我更愿意这样做,理由有以下两点:
- 有时候会出现成环问题,直接规避
- 这是关于建模的正确性问题。简单来说就是你的建模,也就是你对问题空间和结构的定义,是你对整个问题的解答证明的过程,你如果定义好了,就得在操作的每一刻都要满足你建模的状态,这样当出现问题你debug时候才容易做,所以这是很重要的。是一个很重要的编程习惯和证明问题。回归本题,我的建模是:新建一个链表来做答案连接,于是这个新的链表也要满足末尾是null,每时刻都满足。于是就需要每次取完节点后,pre.next=null
代码如下:
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode head = new ListNode();
ListNode pre = head;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
pre.next = l1;
l1 = l1.next;
pre = pre.next;
} else {
pre.next = l2;
l2 = l2.next;
pre = pre.next;
}
pre.next = null;
}
pre.next = l1 == null ? l2 : l1;
return head.next;
}