Day 16 : Remove Nth Node From End of List

今天直接来看题目的叙述: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,所以如果题目给的是双向链结,解题就会相对容易。
https://ithelp.ithome.com.tw/upload/images/20211001/20141729bVoCvPoBUO.png

那我们现在既然不能直接从後面开始倒过来拜访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其实这题就解决了!

不过,我们应该还要还要考虑到

  1. 我们根本不知道4的前面是3
    那我们应该怎麽做?
    我们在还可以知道4的前面是3的时候应该是second指标将要移到null的时候,也就是在共同前进的while判断应该要停止在second.next === null 之前

  2. 万一今天n换成5,一开始走了5步後会变成如下,也就是我们就把头砍掉即可

    			    1 → 2 → 3 → 4 → 5 → null
    step1			^                    ^
    			    F                    S
    
  3. 不要忘记有下面这种情况,

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


<<:  Day17 JavaScript基本教学(二)

>>:  [Day16] THM Tomghost

Day 09 : 操作基础篇 6 — 让 Obsidian 变得更好用!分享我的 Obsidian 笔记版面配置

前言 这是 Obsidian 使用教学 — 基础篇的第 6 篇文章。 在 上一篇文章 中,我介绍了替...

用React刻自己的投资Dashboard Day5 - 多张图表渲染(Rendering lists)

tags: 2021铁人赛 React 上一篇只画了一张图表,投资怎麽可能只需要看一张图呢?这边就再...

Day 16. UX/UI 设计流程之四: Wireflow,并以 Axure RP 实作 (下)

我们平常可能不太会注意到,ajax 网页、APP 里的每一个页面,其实不是单一静态的,而是伴随着多种...

IT铁人DAY 1-进入物件导向世界前的心理准备

  在开始之前,还是很惊讶自己有天可以在这里写文章,分享自身所学的IT技术,提供给大家参考。那其实我...

Day6_HTML语法3

接下来几天会陆陆续续带给大家各种元素使用,会有程序码以及网页呈现的样子,大家可以跟着做做看会更了解,...