动图:删除链表的倒数第 N 个结点
本文主要介绍一道面试中常考链表删除相关的题目,即 leetcode 19. 删除链表的倒数第 N 个结点。采用 双指针 + 动图 的方式进行剖析,供大家参考,希望对大家有所帮组。
19. 删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
进阶:你能尝试使用一趟扫描实现吗?



解题思路
在链表中要删除某个节点 nodeB,必须先找到 该节点的前一节点 nodeA ,再将 nodeA 指向 nodeB 的下一节点 nodeC ,从而实现节点 nodeB 的删除。
例如要删除链表 L(1->2->3->4->5) 中 值为 3 的节点,首先得找到该节点的前一节点(值为 2 的节点),才能实现该节点的删除,如下图示:


题目要求删除 倒数第 n 个 节点,所以首先得找到 该节点的前一节点 ,但由于不知道 整个链表的长度,因此不知道 待删除的节点是正数的第几个节点,所以很难从头节点开始遍历时删除掉这个节点。
思路一
先遍历一遍链表,获取整个链表的长度;假设整个链表的长度为 l,则可知要删除的节点为第 l - n + 1 个节点;再遍历一遍,删除倒数第 n 个节点。例如链表 L 为 1->2->3->4->5,n = 3,则要删除的节点为 第 5 - 3 + 1 = 3 个节点 。
思路二
尽管思路一可行,但是需要 遍历链表两遍,不够简洁,而且题目的 进阶 中也提到尝试使用一趟扫描实现,因此本文采用 双指针 的策略,实现通过一次扫描删除 倒数第 n 个节点 。
在上一期链表相关专题 虚拟头节点秒杀链表问题 中提到 增加虚拟头节点 的策略解决链表问题,增加虚拟头节点的 好处 在于:不需要单独考虑头节点,这样对头节点的处理就像跟其它节点一样。本文也同样采用这种策略。
举栗
以链表 1->2->3->4->5,n = 3 为栗,如下如示。


按照上面分析,先要找到 倒数第 3 个节点的前一节点,即值为 2 的节点;


增加虚拟头节点


值为 2 的节点是 倒数第 4 个节点(后往前数),增加两指针 fast/slow,分别指向最后一个元素(NULL)和上图中 target 的位置;


此时 fast 跟 slow 之间的间距是固定(n = 3)的,找到 target(slow)后,只需要删除其下一节点即可,但 slow 指向的节点前面有多少个节点该如何确定呢?
由于当前已知 fast 和 slow 指向节点之间的长度是固定的,只需要将这两个指针向前挪,直到 slow 挪到虚拟头节点(值为 0)的位置,此时 fast 指向值为 4 的节点的位置,fast 只需要由虚拟头节点的位置 右移 n + 1 = 4 即可。如下图示:


当 fast 右移至值为 4 的节点时,指针 slow 和 fast 同时右移,直至 fast 移到 NULL,此时 slow 刚好到 target 位置,即指向 倒数第 n + 1 个节点,如下图示。


Show me the Code
c++

1 ListNode* removeNthFromEnd(ListNode* head, int n) {
2 ListNode* dummyHead = new ListNode(0);
3 dummyHead->next = head;
4 ListNode *slow = dummyHead, *fast = dummyHead;
5 for (int i = 0; i < n + 1; ++i) {
6 fast = fast->next;
7 }
8
9 while (fast != NULL) {
10 slow = slow->next;
11 fast = fast->next;
12 }
13
14 ListNode* delNode = slow->next;
15 slow->next = delNode->next;
16 delete delNode;
17
18 ListNode* retNode = dummyHead->next;
19 delete dummyHead;
20
21 return retNode;
22 }
java

1 ListNode removeNthFromEnd(ListNode head, int n) {
2 ListNode dummyHead = new ListNode(0);
3 dummyHead.next = head;
4 ListNode slow = dummyHead, fast = dummyHead;
5 for (int i = 0; i < n + 1; ++i) {
6 fast = fast.next;
7 }
8
9 while (fast != null) {
10 slow = slow.next;
11 fast = fast.next;
12 }
13
14 slow.next = slow.next.next;
15 return dummyHead.next;
16 }
动图:删除链表的倒数第 N 个结点的更多相关文章
- 2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案
2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案 1.题目描述 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. ...
- 19. 删除链表的倒数第 N 个结点
目录 19.删除链表的倒数第N个节点 题目 题解-暴力 题解-哈希表 题解-双指针 19.删除链表的倒数第N个节点 题目 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. 输入:he ...
- 【力扣】19. 删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. 进阶:你能尝试使用一趟扫描实现吗? 示例 1: 输入:head = [1,2,3,4,5], n = 2输出:[1,2,3,5]示例 ...
- 打败算法 —— 删除链表的倒数第n个结点
本文参考 出自LeetCode上的题库 -- 删除链表的倒数第n个结点,官方的双指针解法没有完全符合"只遍历一遍链表"的要求,本文给出另一种双指针解法 https://leetco ...
- 【链表】【leetCode高频】: 19. 删除链表的倒数第 N 个结点
1.题目描述 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. 2.算法分析 知识补充: . 分析: 题目要求是删除链表中倒数第N个结点.可以使用两个指针slow,fast. 重点是 ...
- 【算法训练营day4】LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表II
[算法训练营day4]LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表 ...
- 【LeetCode】19. Remove Nth Node From End of List 删除链表的倒数第 N 个结点
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 个人公众号:负雪明烛 本文关键词:链表, 删除节点,双指针,题解,leetcode, 力扣 ...
- LeetCode Remove Nth Node From End of List 删除链表的倒数第n个结点
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode ...
- 19. 删除链表的倒数第N个节点
19. 删除链表的倒数第N个节点 题意 删除链表的倒数第N个结点 解题思路 先让快结点移动n个位置,接着再让慢结点和快结点同时移动,发现出慢结点就是要删除的结点,将前结点指向删除结点的下一个结点即可: ...
随机推荐
- Captain technology INC:高性能电池助力新能源车企销量暴涨
来自七个欧洲国家的11个合作伙伴共聚一堂,投身于HyFlow研究项目,共同开发一种可兼顾高性能和能源需求的混合氧化还原液流储能系统.为此,科学家们希望将高性能钒氧化还原液流电池与超级电容器相结合. 到 ...
- 下一代币王花落谁家?是否是BGV更胜一筹呢?
BGV作为Baccarat的平台币横空出世,通过BGV来激励拥有NGK的用户.在共识算法上,Baccarat 在共识层采用了混合机制 DPOSS共识机制,这是维护 Baccarat 生态体系良性发展的 ...
- linux下安装mysql8.0.x步骤
1.下载mysql mysql官网:https://dev.mysql.com/downloads/mysql/ 将下载的mysql上传打linux 2.解压并重命名 [root@rsyncClien ...
- 随手一记,关于Java日期时间格式化
在Java中,我们大多数情况下格式化日期都是使用simpleDateFormat,比如把一个日期格式化成:2019-12-31的形式,我们一般定义模板为:yyyy-MM-dd的形式. 我们需要注意的是 ...
- EasyExcel学习
导入依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</a ...
- Vue学习笔记-Windows系统Git安装(按装vue-element-admin报错)
一 使用环境: windows 7 64位操作系统 二 Windows系统Git安装(Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理,是目前使用范围最广的版 ...
- vue之下拉菜单Dropdown的使用
通过组件slot来设置下拉触发的元素以及需要通过具名slot为dropdown 来设置下拉菜单.默认情况下,下拉按钮只要hover即可,无需点击也会显示下拉菜单. <el-dropdown> ...
- `curl -L` 解决 GitHub 的 raw.githubusercontent.com 无法连接问题
解决 GitHub 的 raw.githubusercontent.com 无法连接问题 在使用 curl 下载文件时,如果出现以下情况 curl: (7) Failed to connect to ...
- 《C++ Primer》笔记 第1章 开始
输出运算符<< 的计算结果就是其左侧运算对象 std::endl 结束当前行,并将与设备关联的缓冲区中的内容刷到设备中. 程序员常常在调试时添加打印语句.这类语句应该保证"一直& ...
- C#的常见集合接口提供的功能
C#的常见集合接口提供的功能 这里的功能都是泛型版本的常见功能,列出来,也许后面用得上吧,没有放非泛型版本,因为觉得用得不多,也就没有整理 IEnumerable<T> ICollecti ...