LC19. 删除链表的倒数第 N 个结点
删除链表的倒数第N个结点(中等)
Q:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例:
示例一:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例二:
输入:head = [1], n = 1
输出:[]
实例三:
输入:head = [1,2], n = 1
输出:[1]
A:思路:对于本题来讲,其本质仍为删除链表中的某个结点,而想要删除链表中的结点,则一般需要找到待删除结点的上一个结点,然后改变next指针即可。
该题的需求是删除倒数第n个结点,那么我们的任务就分为了两步,第一步是找到待删除结点的上一个结点(为了方便删除),第二是更改next指针指向即可。很显然,该题的难点在于:如何去找到倒数第n个结点的上一个结点呢。归根结底,我们其实需要找的是倒数第 n + 1 个结点(第一步),而删除的是倒数第 n 个结点(第二步)。
对于链表这一类的题来讲,我们最好都去创建一个虚拟哑结点去指向头结点,这么做的目的就是:插入或删除链表中的任何结点都是很方便的。我们知道,在链表中头和尾是比较特殊的,一个没有前驱,一个没有后继,尤其是操作头结点时,若有了虚拟哑结点那就相当方便和简洁了。接下来开始解题,分两步走:
第一步:找到第 n + 1 个结点(利用快慢双指针)
定义两个快慢指针slow和fast,起始均指向dummyNode,随后为了使得后续同时移动快慢指针时,使得二者之间的距离恒为 n + 1 ,故先让fast移动 n + 1次。
即:
while(n != 0 && fast != null){ // while循环中移动了n次
fast = fast.next;
--n;
}
fast = fast.next; // 这里再移动一次,fast一共移动了n + 1次
此时,fast指向了正数第 n + 2个结点,但是我们要找的是倒数第 n + 1个结点。现在哑结点和fast指针所指结点之间是一共有 n 个结点的,随后,当fast != null时,同时移动fast和slow,当fast指向null时,slow正好指向了倒数第 n + 1个结点。
即:
while(fast != null){ // 当fast不为空时,同时移动slow和fast
fast = fast.next; // fast最终指向了null
slow = slow.next; // slow最终指向了待删除节点的上一个结点,即倒数 n + 1 个结点
}
第二步:删除的是倒数第 n 个结点
当找到倒数第 n + 1个结点后,删除就非常简单了,利用 slow.next = slow.next.next 即可。
这里也要注意一点的就是,删除结点对于不用的编程语言来讲,并非是slow.next = slow.next.next 就万事大吉了。这只是在逻辑上的删除,而在物理即内存中并不一定就被删除掉了。对于Java语言来说,我们并不需要做多余的操作,垃圾回收器gc会帮我们去回收该结点并释放内存;但对于C++来讲,就需要手动的去删除和释放内存空间了,毕竟偏底层的高级语言可以较为直接的去操作内存,即是优点但也可能是个缺点,所以对于C++来说,逻辑上删除后,还需要物理上的手动删除,即最后的删除操作应为① ListNode temp = slow.next; ②slow.next = slow.next.next; ③ delete(temp);
以下是Java代码,仅供参考:
/**
* 这里是链表结构的定义,面试中也有可能考察,需要会写出。
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyNode = new ListNode(0, head); // 1. 定义一个哑结点,并初始指向头结点
ListNode fast = dummyNode, slow = dummyNode; // 2. 分别定义一个快指针fast和慢指针slow均初始指向哑结点 while(n != 0 && fast != null){ // 3. 在保证fast不为空指针的情况下将其向前挪动 n 次
fast = fast.next;
--n;
}
fast = fast.next; // 4. fast往后多移动一位,为了使得后面slow和fast一起移动时,slow最终可以指向待删除节点的上一个节点,也是为了删除方便
while(fast != null){ // 5. 当fast不为空时,同时移动slow和fast
fast = fast.next; // 6. fast最终指向了null
slow = slow.next; // 7. slow最终指向了待删除节点的上一个结点,即倒数 n + 1 个结点处
}
slow.next = slow.next.next; // 8. 更改slow的next指针,以删除倒数第 n 个结点
return dummyNode.next; // 9. 返回哑结点的下一个结点,即head结点
}
}
LC19. 删除链表的倒数第 N 个结点的更多相关文章
- 动图:删除链表的倒数第 N 个结点
本文主要介绍一道面试中常考链表删除相关的题目,即 leetcode 19. 删除链表的倒数第 N 个结点.采用 双指针 + 动图 的方式进行剖析,供大家参考,希望对大家有所帮组. 19. 删除链表的倒 ...
- 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. 环形链表 ...
- 四种语言刷算法之删除链表的倒数第 N 个结点
力扣19. 删除链表的倒数第 N 个结点 1.C /** * Definition for singly-linked list. * struct ListNode { * int v ...
- 【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 ...
随机推荐
- K8S 性能优化 - OS sysctl 调优
前言 K8S 性能优化系列文章,本文为第一篇:OS sysctl 性能优化参数最佳实践. 参数一览 sysctl 调优参数一览 # Kubernetes Settings vm.max_map_cou ...
- Django+bootstrap+layui集成
一.django项目搭建:1.Python安装2.下载Django解压到Python安装目录G:\python3.7.4\3.cmd G:\python3.7.4\Django-4.0.5 执行 py ...
- ArchLinux 作业系统安装教程
如果你能看到此文,想必你一定玩过不少的发行商发行的 Linux 作业系统或者听说过很多发行商发行的 Linux 作业系统.如果你玩过不少的 Linux 作业系统,对于安装系统可谓是轻车熟路,就是闭着眼 ...
- 杂谈--User Story
本篇用于给自己后续慢慢看,对敏捷感兴趣的小伙伴,可以自行去看官方文档或者各种网站的视频讲解,更详细. 对于敏捷开发来说,User Story是开发的基础,把原本需求拆成最小粒度的Story,以方便拆分 ...
- 打工人都在用的AI工具(第一期)
更多精彩内容,欢迎关注公众号:数量技术宅,也可添加技术宅个人微信号:sljsz01,与我交流. 随着ChatGPT的问世,AI也算迎来了高光时刻!下文是技术宅整理的一些和ChatGPT相关的工具应用, ...
- 利用Karlibr生成April标定板图像
1 关键的命令 rosrun kalibr kalibr_create_target_pdf --type apriltag --nx 6 --ny 6 --tsize 0.02 --tspace 0 ...
- ES6let const
let const class 类 import 引入模块 export 暴露接口 // var a = 10; // let b = 20; // const c = 30; var和let比 co ...
- '林子雨大数据' 实验3 HBase操作与接口编程
"林子雨大数据" 实验3 HBase操作与接口编程 环境搭建 VM虚拟机和Ubuntu系统的安装 在Windows中使用VirtualBox安装Ubuntu虚拟机(2020年7月版 ...
- 1、kubernetes概念
一.kubernetes简介 kubernetes的本质是一组服务器集群.它可以在每个节点上运行特定的程序,来对节点中的容器进行管理.目的是为了实现资源管理的自动化. 主要功能如下: 1.自我修复:一 ...
- HTTP协议初见
HTTP协议 四大特性 基于请求端响应 客户端发送请求,服务端才响应,服务端不会主动给客户端发送响应. 基于TCP/IP作用于应用层之上的协议 此协议属于应用层 无状态 服务端不会保存客户 ...