剑指–合并两个排序的链表
1,题目:

2,思路:
方法一:引入伪头结点(思路还是正常思路)
引入伪头节点: 由于初始状态合并链表中无节点,因此循环第一轮时无法将节点添加到合并链表中。解决方案:初始化一个辅助节点 dum 作为合并链表的伪头节点,将各节点添加至 dum 之后。
算法流程:
-
1.初始化: 伪头节点 dum ,节点 cur 指向 dum。
-
2.循环合并: 当l1或l2为空时跳出;
-
当l1.val<l2.val 时: cur 的后继节点指定为 l1,并l1向前走一步;
-
当 l1.val≥l2.val 时: cur 的后继节点指定为 l2,并l2向前走一步 ;
-
节点 cur 向前走一步,即cur=cur.next 。
-
-
3.合并剩余尾部: 跳出时有两种情况,即 l1为空 或l2为空。
-
若 l1 !=null : 将l1添加至节点 cur 之后;
-
否则: 将l2添加至节点 cur 之后。
-
-
4.返回值: 合并链表在伪头节点 dum 之后,因此返回dum.next 即可。
下面是对应的图解:
















方法二:递归写法:
递归的写法:
递归算法 用一个新的指针来保存合并的代码 新链表的next指向下一个比较后的节点,如果是l1的节点则l1指针往后移动,如果是l2的节点则将l2的指针后移。
3,代码:
方法一:引入伪头结点(思路还是正常思路)
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
/*
引入伪头节点: 由于初始状态合并链表中无节点,因此循环第一轮时无法将节点添加到合并链表中。解决方案:初始化一个辅助节点 dum 作为合并链表的伪头节点,将各节点添加至 dum 之后。
算法流程:
1.初始化: 伪头节点 dum ,节点 cur 指向 dum。
2.循环合并: 当l1或l2为空时跳出;
当l1.val<l2.val 时: cur 的后继节点指定为 l1,并l1向前走一步;
当 l1.val≥l2.val 时: cur 的后继节点指定为 l2,并l2向前走一步 ;
节点 cur 向前走一步,即cur=cur.next 。
3.合并剩余尾部: 跳出时有两种情况,即 l1为空 或l2为空。
若 l1 !=null : 将l1添加至节点 cur 之后;
否则: 将l2添加至节点 cur 之后。
4.返回值: 合并链表在伪头节点 dum 之后,因此返回dum.next 即可。
*/
ListNode dum = new ListNode(0), cur = dum;//新建一个链表,并且cur指针指向头结点
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;
}
cur.next = l1 != null ? l1 : l2;//这是合并剩下的节点
return dum.next;
}
}
这一个写法和上面的是一样的(非递归):
class Solution {
public ListNode mergeTwoLists(ListNode linked1, ListNode linked2) {
//非递归:
/*
因为链表是升序的,我们只需要遍历每个链表的头,比较一下哪个小就把哪个链表的头拿出来放到新的链表中,一直这样循环,直到有一个链表为空,然后我们再把另一个不为空的链表挂到新的链表中。
*/
//下面4行是空判断
if (linked1 == null)
return linked2;
if (linked2 == null)
return linked1;
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while (linked1 != null && linked2 != null) {
//比较一下,哪个小就把哪个放到新的链表中
if (linked1.val <= linked2.val) {
curr.next = linked1;
linked1 = linked1.next;
} else {
curr.next = linked2;
linked2 = linked2.next;
}
curr = curr.next;
}
//然后把那个不为空的链表挂到新的链表中
curr.next = linked1 == null ? linked2 : linked1;
return dummy.next;
}
}
方法二:递归写法:
class Solution {
public ListNode mergeTwoLists(ListNode linked1, ListNode linked2) {
//递归的写法
//递归算法 用一个新的指针来保存合并的代码 新链表的next指向下一个比较后的节点,如果是l1的节点则l1指针往后移动,如果是l2的节点则将l2的指针后移。
if (linked1 == null)
return linked2;
if (linked2 == null)
return linked1;
if (linked1.val < linked2.val) {
linked1.next = mergeTwoLists(linked1.next, linked2);
return linked1;
} else {
linked2.next = mergeTwoLists(linked1, linked2.next);
return linked2;
}
}
}
本文介绍两种方法合并两个已排序的链表,一种是非递归方式,通过引入伪头结点进行循环合并,另一种是递归方式,通过比较两链表头结点值,将较小者加入新链表。
114

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



