【刷题日记】进阶版本的 19. 删除链表的倒数第 N 个结点

简介: 本次刷题日记的第 19 篇,力扣题为:进阶版本的 19. 删除链表的倒数第 N 个结点 ,中等

【刷题日记】进阶版本的 19. 删除链表的倒数第 N 个结点

本次刷题日记的第 19 篇,力扣题为:进阶版本的 19. 删除链表的倒数第 N 个结点中等

一、题目描述:

image.png

我们上一题做了 19. 删除链表的倒数第 N 个结点 ,做完了之后,xdm 有没有发现,我们其实是扫描了 2 次链表的,如果链表比较长的话,其实这种方式还是比较低效的

题目中有说到,我们是否可以使用一次扫描实现这套题?

能实现吗?必须能实现呀,咱们刷一个题不是刷完就完了的,还需要去分析他如何去解决才会更好更快,更健壮

就像工作中,咱们做一件事情,不是做完了就算了,还需要复盘,总结高效的经验的


1、这道题考察了什么思想?你的思路是什么?

我们也刷了一遍这个题了,那么我们如何只遍历一次链表,就能实现呢?

根据上次我们刷题的经验,我们知道如何找到找到倒数第 n 个节点,并删除他

我们先计算了 整个链表的长度,然后通过计算,算出了我们需要从头偏移多少次

那么这一次,我们是否可以在从头偏移指针的时候,我们自己就知道偏移到哪个位置就可以停下来呢?不需要去可以计算链表的长度


那么我们可以模拟一下:

看下图,如果有一个红指针和一个黑指针相差固定的距离,那么当黑指针先前走一步的时候,红指针也会向前走一步,直到黑指针都到链表尾部的时候,才会停止

image.png

那么这个时候,红指针和黑指针的距离一直是不会改变的,严格保持车距,不超车,也不会跟丢

我们回过头来思考一下,这个红指针是不是就相当于是倒数第 n 个节点呢?

如果我们要删除倒数第 n 个节点,那么我们也可以使用这样的方式,遍历一遍链表是不是就可以找到倒数第 n 个节点了呢?

那么同样的道理,既然我们是要删除倒数第 n 个节点,那么我们就要找到倒数第 n 个节点的前 1 个节点,这样便于我们链表操作的时候,删除需要删除的节点

那么,我们就直接一点,直接加入一个帮助节点,放到链表的头,让他从一开始就满足我们要找到删除节点的前一个节点,类似于下面这个样

image.png

上面紫色的节点便是我们需要删除的节点了,这一块的操作和之前的上一篇的做法一致,这里就不赘述了

那么接下来就是按照思路来翻译代码了 , 这其实就是使用双指针的方式来处理这个题,关于双指针处理题目的场景还是非常多的



三、编码

根据上述逻辑和分析,我们就可以翻译成如下代码,注意快慢指针的处理

编码如下:

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func removeNthFromEnd(head *ListNode, n int) *ListNode {
    // 定义一个帮助节点,放在整个链表的前面一个节点上,值域我们可以默认为0,定义为其他的数字也没有问题
    helper := &ListNode{0, head}
    // 定义一个快指针一个慢指针
    quick, slow := head, helper
    // 快指针先跑 n 次
    for i := 0; i < n; i++ {
        quick = quick.Next
    }
    // 快指针跑一次,慢指针跑一次,慢指针总是要多偏移 n+1 次才能追上 quick 指针
    for ; quick != nil; quick = quick.Next {
        slow = slow.Next
    }
    // 找到要删除节点是 慢指针的下一个节点
    slow.Next = slow.Next.Next
    return helper.Next
}

看了上述编码,还是比较清晰的吧,编码的逻辑和推演的逻辑一致,足够简单,足够好懂

只需要处理好 快慢指针的逻辑即可实现,这实现了扫描一边链表,便完成删除链表的倒数第 n 个节点,nice

四、总结:

该题的时间复杂度是 O(n) ,这个 n 是链表的长度,因为我们遍历了它,空间复杂度是 O(1) ,我们只引入了常数级别的空间消耗

原题地址:19. 删除链表的倒数第 N 个结点

今天就到这里,学习所得,若有偏差,还请斧正

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

image.png

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~


相关文章
|
1月前
|
算法
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
69 1
|
22天前
|
存储 算法 搜索推荐
链表的中间结点
【10月更文挑战第24天】链表的中间结点是链表操作中的一个重要概念,通过快慢指针法等方法可以高效地找到它。中间结点在数据分割、平衡检测、算法应用等方面都有着重要的意义。在实际编程中,理解和掌握寻找中间结点的方法对于解决链表相关问题具有重要价值。
13 1
|
1月前
Leetcode第十九题(删除链表的倒数第N个节点)
LeetCode第19题要求删除链表的倒数第N个节点,可以通过快慢指针法在一次遍历中实现。
44 0
Leetcode第十九题(删除链表的倒数第N个节点)
|
1月前
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
49 0
|
1月前
【LeetCode 09】19 删除链表的倒数第 N 个结点
【LeetCode 09】19 删除链表的倒数第 N 个结点
17 0
|
6月前
【移除链表元素】LeetCode第203题讲解
【移除链表元素】LeetCode第203题讲解
|
5月前
|
存储 SQL 算法
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
|
5月前
|
存储 SQL 算法
LeetCode 题目 86:分隔链表
LeetCode 题目 86:分隔链表
|
5月前
|
存储 算法 Java
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
54 2
|
6月前
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点.
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点
53 1