每日:删除链表倒数第 N 个结点

开发 前端
需要删除链表中的倒数第 n 个节点,我们需要知道的就是倒数第 n+1 个节点,然后删除删除倒数第 n+1 节点的后继节点即可。

[[416447]]

本文转载自微信公众号「三分钟学前端」,作者sisterAn。转载本文请联系三分钟学前端公众号。

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

  1. 给定一个链表: 1->2->3->4->5, 和 n = 2. 
  2. 当删除了倒数第二个节点后,链表变为 1->2->3->5. 

说明:

给定的 n 保证是有效的。

进阶:

你能尝试使用一趟扫描实现吗?

解法:快慢指针

解题思路: 需要删除链表中的倒数第 n 个节点,我们需要知道的就是倒数第 n+1 个节点,然后删除删除倒数第 n+1 节点的后继节点即可

步骤:

使用 2 个指针:

  • fast 快指针提前走 n+1 步
  • slow 指针指向当前距离 fast 倒数第 n 个节点, 初始为 head

然后, fast 、 slow 同步向前走,直到 fast.next 为 null

此时,fast 为最后一个节点,slow 就是倒数第 n+1 个节点,此时问题就变更为删除链表中的 slow 的后继节点

但存在一个问题,当链表长度为 n 时,fast 是前进不到 n+1 个节点位置的,所以此时有两种解决思路:

  • 创建一个头节点 preHead ,设置 preHead.next = head ,这样就可以解决以上问题,删除倒数第 n 个节点后,返回的 preHead.next 即可
  • 另外一种是,fast 快指针提前走 n 步后,判断 fast.next 是否为 null ,即 fast 是否是最后一个节点,如果是,则 head 为倒数第 n 个节点,此时问题可以简化为删除头节点;如果不是, fast = fast.next ,fast 再前进一步,slow 为倒数第 n+1 个节点,也解决了以上问题。

解决方案一:添加 preHead 节点

  1. const removeNthFromEnd = function(head, n) { 
  2.     let preHead = new ListNode(0) 
  3.     preHead.next = head 
  4.     let fast = preHead, slow = preHead 
  5.     // 快先走 n+1 步 
  6.     while(n--) { 
  7.         fast = fast.next 
  8.     } 
  9.     // fast、slow 一起前进 
  10.     while(fast && fast.next) { 
  11.         fast = fast.next 
  12.         slow = slow.next 
  13.     } 
  14.     slow.next = slow.next.next 
  15.     return preHead.next 
  16. }; 

解决方案二:单独处理倒数第 n 节点

  1. const removeNthFromEnd = function(head, n) { 
  2.     let fast = head, slow = head 
  3.     // 快先走 n 步 
  4.     while(--n) { 
  5.         fast = fast.next 
  6.     } 
  7.     if(!fast.nextreturn head.next 
  8.     fast = fast.next 
  9.     // fast、slow 一起前进 
  10.     while(fast && fast.next) { 
  11.         fast = fast.next 
  12.         slow = slow.next 
  13.     } 
  14.     slow.next = slow.next.next 
  15.     return head 
  16. }; 

时间复杂度:O(n)

空间复杂度:O(1)

 

来源:https://github.com/sisterAn/JavaScript-Algorithms

 

责任编辑:武晓燕 来源: 三分钟学前端
相关推荐

2022-01-17 09:23:02

LeetCode删除链表算法

2021-04-14 10:19:18

链表倒数结点

2021-02-03 13:23:42

链表倒数结点

2020-10-19 13:27:19

链表倒数结点

2022-06-01 06:58:41

节点链表倒数

2023-04-17 07:33:11

反转链表移除链表

2012-06-19 14:23:04

云计算中国

2012-02-17 09:45:04

网速手机

2012-02-17 09:43:13

手机网速移动互联

2021-02-04 08:18:53

LeetCode链表

2012-08-10 10:53:03

云计算BSA商业软件联盟

2012-06-18 10:07:17

云计算实力榜

2021-09-22 22:57:41

手机流量通信

2018-03-01 13:32:28

宏碁游戏本PC行业

2011-08-08 10:53:55

宝德PR2510N云计算

2012-02-21 17:17:51

手机网速网速

2010-11-15 10:49:23

求职

2022-11-14 14:55:05

软件开发程序员薪资

2022-03-07 11:03:08

大数据检测谷歌

2021-08-26 10:07:25

数组前端元素
点赞
收藏

51CTO技术栈公众号