【刷题日记】进阶版本的 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

好了,本次就到这里

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

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


相关文章
|
6天前
19 删除链表的倒数第 N 个结点
19 删除链表的倒数第 N 个结点
|
6天前
|
存储 Java
高效删除链表倒数节点最优实现
要删除链表的倒数第 n 个节点,并返回链表的头节点,我们可以使用一趟扫描的方法来实现。这个方法涉及使用两个指针:快指针和慢指针。
|
6天前
19. 删除链表的倒数第 N 个结点
19. 删除链表的倒数第 N 个结点
|
6天前
|
存储
三种方法实现获取链表中的倒数第n个元素
三种方法实现获取链表中的倒数第n个元素
15 0
|
6天前
【力扣】19. 删除链表的倒数第 N 个结点
【力扣】19. 删除链表的倒数第 N 个结点
数据结构|双向链表|带头结点|头插|尾插|尾删|头删
数据结构|双向链表|带头结点|头插|尾插|尾删|头删
|
6天前
|
算法
算法系列--链表刷题(二)(下)
算法系列--链表刷题(二)(下)
18 0
|
6天前
数据结构--链表刷题(一)快慢指针(上)
数据结构--链表刷题(一)快慢指针
16 0
|
6天前
|
算法
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
|
6天前
【移除链表元素】LeetCode第203题讲解
【移除链表元素】LeetCode第203题讲解