1、题目描述
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = [] 输出:[]
示例 3:
输入:l1 = [], l2 = [0] 输出:[0]
提示:
- 两个链表的节点数目范围是
[0, 50]
-100 <= Node.val <= 100
l1
和l2
均按 非递减顺序 排列
2、解题思路
-
双指针遍历:用两个指针
node1
和node2
分别遍历两个链表。 -
比较节点值:每次比较
node1.val
和node2.val
,将较小的节点接入新链表。 -
处理剩余节点:当一个链表遍历完后,直接将另一个链表的剩余部分接在新链表末尾。
具体步骤
(1) 初始化
-
创建一个 虚拟头节点
dummy
(方便统一处理头节点)。 -
定义一个指针
current
指向dummy
,用于构建新链表。
(2) 双指针遍历
-
循环条件:
while (node1 != null && node2 != null)
(两个链表均未遍历完时):-
比较
node1.val
和node2.val
:-
如果
node1.val <= node2.val
:-
将
node1
接入current.next
。 -
移动
node1
到node1.next
。
-
-
否则:
-
将
node2
接入current.next
。 -
移动
node2
到node2.next
。
-
-
-
移动
current
:current = current.next
(保持current
指向新链表末尾)。
-
(3) 处理剩余节点
-
退出循环后,至少有一个链表已遍历完:
-
如果
node1
不为空,将current.next
指向node1
。 -
如果
node2
不为空,将current.next
指向node2
。
-
(4) 返回结果
-
最终返回
dummy.next
(即新链表的真实头节点)。
public ListNode mergeTwoLists(ListNode node1, ListNode node2) {
if (node1 == null) return node2;
if (node2 == null) return node1;
ListNode dummy = new ListNode(-1);
ListNode current = dummy;
while(node1 != null && node2 != null){
if(node1.val <= node2.val){
current.next = node1;
node1 = node1.next;
}else{
current.next = node2;
node2 = node2.next;
}
current = current.next;
}
current.next = node1 != null ? node1:node2;
return dummy.next;
}
复杂度分析
-
时间复杂度:O(n + m)(遍历两个链表各一次)。
-
空间复杂度:O(1)(仅使用常数级额外空间)。