携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情
LeetCode 1669:合并两个链表
题目描述
给你两个链表 list1 和 list2 ,它们包含的元素分别为 n 个和 m 个。
请你将 list1 中下标从 a 到 b 的全部节点都删除,并将list2 接在被删除节点的位置。
下图中蓝色边和节点展示了操作后的结果:
解题思路
思路一
-
新建哑节点
dummy node,便于返回结果; -
分别找到下标为a - 1、b + 1的节点标记为prev, curr;
for (let i = 1; i <= a; i++) {
prev = curr;
curr = curr.next;
}
for (let j = a; j <= b; j++) {
curr = curr.next;
}
- 找到链表list2的最后一个节点
var tail = list2;
while (tail.next != null) {
tail = tail.next;
}
- 然后将
prev节点的next指向list2,list2的尾节点tail的next指向curr; - 最后返回
dummy.next
完整代码如下:
/**
* @param {ListNode} list1
* @param {number} a
* @param {number} b
* @param {ListNode} list2
* @return {ListNode}
*/
var mergeInBetween = function (list1, a, b, list2) {
let dummy = new ListNode(0, list1);
let prev,
curr = list1;
for (let i = 1; i <= a; i++) {
prev = curr;
curr = curr.next;
}
for (let j = a; j <= b; j++) {
curr = curr.next;
}
let tail = list2;
while (tail.next != null) {
tail = tail.next;
}
prev.next = list2;
tail.next = curr;
return dummy.next;
};
时间复杂度: O(b + m); 遍历b次找到下标b的节点curr, 遍历m次找到链表list2的尾节点, 所以时间复杂度为O(b + m);
空间复杂度: O(1);
或者优化下:
var mergeInBetween = function(list1, a, b, list2) {
let curr = list1;
// 遍历到 a 前面一个节点, a 前面的节点无需操作
for (let i = 1; i < a ; i++) {
curr = curr.next;
}
// 过滤掉不需要的节点
let node = curr.next;
for (let i = a; i <= b ; i++) {
node = node.next;
}
// 从 b + 1 位置开始 插入list2
curr.next = list2
while (curr.next) {
curr = curr.next;
}
// list2全部插入之后 指向list1过滤后的所有节点
curr.next = node;
return list1;
};
以上代码中 没有使用哑节点,最终直接返回list1;使用两个临时遍历curr和node