今天直接来看题目的叙述:Given the head of a linked list, remove the nth node from the end of the list and return its head.
也就是我们要从linked list尾端数第n个node并把它移除後,再将它回传。
我们应该如何下手?
今天题目给的事单向连结串列(single linked list),而非双向链接串列如下图 (Doubly linked list),双向链接和单向连结的差异主要是双向可以知道前面和後面的node,所以如果题目给的是双向链结,解题就会相对容易。
那我们现在既然不能直接从後面开始倒过来拜访node,这里就要使用我们在解linked list时常用到的技巧 → pointer 两个指标来追踪
利用范例Input: head = [1,2,3,4,5], n = 2来说明
1 → 2 → 3 → 4 → 5 → null
我们宣告一个First (F)和Second (S)指标来追踪
一开始我们把F和S指标都放在1身上
然後让S走两步( n = 2)来到 3 变成
1 → 2 → 3 → 4 → 5 → null
^ ^
F S
然後们让F和S一起往右移动直到S摸到null为止
来看下面不会动的动画,看会怎麽样
1 → 2 → 3 → 4 → 5 → null
step1 ^ ^
F S
step2 ^ ^
F S
step3 ^ ^
F S
step4 ^ ^
F S
偷看一下leetCode的解答
Output: [1,2,3,5]
有没有发现现在的F刚好就在我们要移除的4身上!!
然後我们就可以把3的next换成5其实这题就解决了!
不过,我们应该还要还要考虑到
我们根本不知道4的前面是3
那我们应该怎麽做?
我们在还可以知道4的前面是3的时候应该是second指标将要移到null的时候,也就是在共同前进的while判断应该要停止在second.next === null 之前
万一今天n换成5,一开始走了5步後会变成如下,也就是我们就把头砍掉即可
1 → 2 → 3 → 4 → 5 → null
step1 ^ ^
F S
不要忘记有下面这种情况,
Input: head = [1], n = 1
Output: []
时间复杂度为:O(n),空间复杂度:O(1)
来看最後的实作
var removeNthFromEnd = function (head, n) {
let step = 1;
let first = head;
let second = head;
// step用来确保我们先移动second的步数
while (step <= n) {
second = second.next;
step++;
}
// 考虑情况二
if (second === null) {
if (head.next) {
head.val = head.next.val;
head.next = head.next.next;
} else {
// 考虑情况三
head = null
}
// 做完就没事了
return head;
}
// 考虑情况一
while (second.next !== null) {
second = second.next;
first = first.next;
}
// second.next === null 时直接把first.next换掉
first.next = first.next.next;
return head;
};
明日题目预告:再玩一题Linked Lists相关题吧!
Add Two Numbers
前言 这是 Obsidian 使用教学 — 基础篇的第 6 篇文章。 在 上一篇文章 中,我介绍了替...
tags: 2021铁人赛 React 上一篇只画了一张图表,投资怎麽可能只需要看一张图呢?这边就再...
我们平常可能不太会注意到,ajax 网页、APP 里的每一个页面,其实不是单一静态的,而是伴随着多种...
在开始之前,还是很惊讶自己有天可以在这里写文章,分享自身所学的IT技术,提供给大家参考。那其实我...
接下来几天会陆陆续续带给大家各种元素使用,会有程序码以及网页呈现的样子,大家可以跟着做做看会更了解,...