合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

思路:
解法一(迭代):
借助两个指针,其分别指向l1的头节点、l2的头节点,每次比较两个链表中指针所指向的值,若l1.val >= l2.val,则选 l1 节点,并将其后移一位(l1 = l1.next);若l1.val < l2.val,则选 l2 节点,并将其后移一位(l2 = l2.next)。
那么现在,问题来了,选出的节点要存放到哪里呢?
关于链表的操作,我喜欢为链表设置虚拟头节点(dummyHead),并设置一个cur指针指向dummyHead,意为当前指针的指向。所以每次选出的节点就可存放为cur.next,每次存放完毕后,将cur后移一位(cur = cur.next)即可,方便下一次存放。当然也可以不设置dummyHead,直接设置head,只不过处理方式不同罢了。
以上操作需要借助while循环来完成,那么循环终止条件是什么呢?这就是接下来我们要解决的问题。
因为两个链表的长度可能不相等,那么当一条链表的所有节点都被选择后,剩下的另一条链表就无法进行上述的比较,会出现空指针错误,或者也可以认为此时已经不需要比较了,因为链表均为有序链表,使 cur .next 指向那条不为空的链表即可解题。所以说,我们的循环终止条件可以是 while(l1 != null && l2 != null) ,也可以是 while(l1 != null || l2 != null) ,只不过处理问题的位置不同,详情可以参考代码。
while(l1 != null && l2 != null) 情况的代码:
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(0);
dummyHead.next = null;
ListNode cur = dummyHead;
while(l1 != null && l2 != null){
if(l1.val <= l2.val){
cur.next = l1;
l1 = l1.next;
}else{
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
if(l1 == null)
cur.next = l2;
if(l2 == null)
cur.next = l1;
return dummyHead.next;
}
while(l1 != null && l2 != null) 情况的代码:
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(0);
dummyHead.next = null;
ListNode cur = dummyHead;
while(l1 != null || l2 != null){
if(l1 == null){
cur.next = l2;
break;
}
if(l2 == null){
cur.next = l1;
break;
}
if(l1.val <= l2.val){
cur.next = l1;
l1 = l1.next;
}else{
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
return dummyHead.next;
}
解法二(递归):
迭代解题完毕后,递归很容易就能想到,只不过迭代通过代码修改指针的方式,递归可以通过传递参数来完成,基本思想与迭代一致。
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(0);
dummyHead.next = null;
ListNode cur = dummyHead;
merge(cur,l1,l2);
return dummyHead.next;
}
public void merge(ListNode cur,ListNode l1,ListNode l2){
if(l1 == null){
cur.next = l2;
return;
}
if(l2 == null){
cur.next = l1;
return;
}
if(l1.val <= l2.val){
cur.next = l1;
merge(cur.next,l1.next,l2);
}else{
cur.next = l2;
merge(cur.next,l1,l2.next);
}
}
总结:

本文详细介绍了如何合并两个已排序的链表,分别使用迭代和递归两种方法。在迭代法中,通过创建虚拟头节点和辅助指针,逐个比较两个链表的节点并合并。在递归法中,通过递归调用实现相同的功能。两种方法都确保了合并后的链表仍然有序。
3181

被折叠的 条评论
为什么被折叠?



