合并有序链表
将两个升序链表合并为一个升序链表
问题
给定两个升序排列的链表,将它们合并为一个新的升序链表并返回。
示例:
- 输入:
1 -> 2 -> 4和1 -> 3 -> 4 - 输出:
1 -> 1 -> 2 -> 3 -> 4 -> 4
解答
链表节点定义
class ListNode {
constructor(val = 0, next = null) {
this.val = val;
this.next = next;
}
}
迭代法
function mergeTwoLists(l1, l2) {
// 创建虚拟头节点,简化边界处理
const dummy = new ListNode(-1);
let current = dummy;
// 同时遍历两个链表
while (l1 !== null && l2 !== null) {
if (l1.val <= l2.val) {
current.next = l1;
l1 = l1.next;
} else {
current.next = l2;
l2 = l2.next;
}
current = current.next;
}
// 拼接剩余部分
current.next = l1 !== null ? l1 : l2;
return dummy.next;
}
递归法
function mergeTwoLists(l1, l2) {
// 递归终止条件
if (l1 === null) return l2;
if (l2 === null) return l1;
// 选择较小的节点,递归处理剩余部分
if (l1.val <= l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
测试代码
// 辅助函数:数组转链表
function arrayToList(arr) {
const dummy = new ListNode();
let current = dummy;
for (const val of arr) {
current.next = new ListNode(val);
current = current.next;
}
return dummy.next;
}
// 辅助函数:链表转数组
function listToArray(head) {
const result = [];
while (head) {
result.push(head.val);
head = head.next;
}
return result;
}
// 测试
const l1 = arrayToList([1, 2, 4]);
const l2 = arrayToList([1, 3, 4]);
const merged = mergeTwoLists(l1, l2);
console.log(listToArray(merged)); // [1, 1, 2, 3, 4, 4]
关键点
- 使用虚拟头节点(dummy node)避免处理头节点的特殊情况
- 迭代法时间复杂度 O(m+n),空间复杂度 O(1)
- 递归法时间复杂度 O(m+n),空间复杂度 O(m+n)(递归栈)
- 循环结束后记得拼接未遍历完的链表
- 两种方法都不需要创建新节点,直接调整指针即可
目录