返回
再探剑指 Offer 025: 合并两个排序的链表(javascript版)
前端
2023-12-24 11:29:51
算法概述
剑指 Offer 025 要求我们合并两个已经排序的链表,并生成一个新的排序链表。为了解决这个问题,我们需要一种高效的方法来比较和合并两个链表的节点。
解决思路
-
初始化:
- 首先,我们创建一个新的链表头节点作为合并后的链表的头节点。
- 然后,我们定义两个指针 curr1 和 curr2,分别指向两个输入链表的头节点。
-
比较和合并:
- 进入一个 while 循环,只要 curr1 和 curr2 都不是空节点,就继续执行循环。
- 在循环体内,我们比较 curr1 和 curr2 所指向的节点的值,将较小的节点的值插入到合并后的链表中。
- 然后,我们让 curr1 和 curr2 指向各自链表的下一个节点。
-
处理剩余节点:
- 当 curr1 和 curr2 中有一个为空节点时,我们将剩余的节点直接连接到合并后的链表的末尾。
-
返回合并后的链表:
- 最后,我们将返回合并后的链表的头节点。
复杂度分析
- 时间复杂度:O(n + m),其中 n 和 m 分别是两个输入链表的长度。
- 空间复杂度:O(1),因为我们没有使用额外的空间来存储临时数据。
优缺点
-
优点:
- 该算法的时间复杂度是线性的,非常高效。
- 它不需要额外的空间来存储临时数据,因此空间复杂度为常数。
- 该算法非常容易理解和实现。
-
缺点:
- 该算法可能会在某些情况下产生一个新的链表,而不是修改其中一个输入链表。
- 如果两个输入链表非常长,可能会导致栈溢出。
示例代码
function mergeTwoLists(head1, head2) {
if (head1 === null) {
return head2;
}
if (head2 === null) {
return head1;
}
let mergedHead;
if (head1.val < head2.val) {
mergedHead = head1;
head1 = head1.next;
} else {
mergedHead = head2;
head2 = head2.next;
}
let current = mergedHead;
while (head1 !== null && head2 !== null) {
if (head1.val < head2.val) {
current.next = head1;
head1 = head1.next;
} else {
current.next = head2;
head2 = head2.next;
}
current = current.next;
}
if (head1 !== null) {
current.next = head1;
}
if (head2 !== null) {
current.next = head2;
}
return mergedHead;
}
总结
剑指 Offer 025 是一个经典的合并两个排序链表的算法问题。它要求我们合并两个已经排序的链表,并生成一个新的排序链表。通过本文的详细讲解,我们掌握了如何使用JavaScript解决这个问题。