【刷题日记】19. 删除链表的倒数第 N 个结点
本次刷题日记的第 18 篇,力扣题为:19. 删除链表的倒数第 N 个结点 ,中等
一、题目描述:
来做一个链表的题,学习链表的时候还是学习 C 语言指针的时候练习的题目,现在我们来回顾一下,今天使用 golang 来刷题
使用 golang 来刷链表的题,在编码过程中,会比 C 语言好写很多,例如 C 语言中获取指针指向的值是->
, a->value , 而 golang 依然是使用 .
,例如 a.value
1、这道题考察了什么思想?你的思路是什么?
我们一起来看看题目给了我们那些重点信息吧:
- 题目会给出一个正常链表,我们需要删除倒数第 n 个节点
题目给的还是非常明确的,问题是我们需要如何来实现呢,还是老规矩,实现前,我们先来分析和推演,思想上弄清楚了,编码就是水到渠成的事情了
就像这样一个节点指向另外一个节点,多个节点拼接起来,就形成了链表
一下子接触这个题,可能不好想到如何删除倒数的第 n 个节点,那么我们可以来推演一下,先来删除正数的第 n 个节点
例如给出一个链表,我们需要删除正向的第 3 个节点,那么我们只需要将打头的第一个指针向后偏移 3 -1 次就可以找到需要删除的节点了
**可是如何才能删除这个节点呢?**我们只需要将该节点的上一个节点的指针指向该节点的下个指针就可以了
可是我们此刻如何知道上一个节点的指针呢?貌似很难
所以,对于这种情况,我们只需要将刚才找节点的方式换一下,换成找到需要删除节点的前一个节点,找到节点后,我们将找到的节点指向该节点的下下个节点就可以了
那么看到这里,对于要删除链表的倒数第 n 个节点,其实我们应该就要有思路的
若链表的节点个数为 x 个,那么需要删除链表的第 n 个节点,我们就只需要从头偏移 x-n 次,就可以指向需要删除的节点了
按照上述原理,我们需要找到要删除节点的前一个,那么我们就只需要偏移 x-n-1 次就可以找到了,然后将该节点的指针,指向下下个节点即可
看了上述思路和推演,相信兄弟们应该清楚了吧,接下来就是翻译代码了
三、编码
根据上述逻辑和分析,我们就可以翻译成如下代码,翻译代码的时候我们需要注意几点:
- 我们需要删除的倒数第 n 个节点,若与链表长度 length 相等,则是删除头结点,我们直接操作即可,无须再去遍历
- 其他的情况直接按照上述逻辑翻译即可
编码如下:
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ // 获取链表的长度 func getLength(head *ListNode) (length int) { for ; head != nil; head = head.Next { length++ } return } func removeNthFromEnd(head *ListNode, n int) *ListNode { length := getLength(head) // 定义一个帮助指针 helper := head // 定义一个用于游动的指针 cur := helper // 如果需要删除的节点是头节点的时候 if n == length{ return head.Next } // 遍历链表,使cur 指针最终指针指向需要删除节点的前一个 for i := 0; i < length-n-1; i++ { cur = cur.Next } cur.Next = cur.Next.Next return helper }
看了上述编码,还是比较清晰的吧,编码的逻辑和推演的逻辑一致,足够简单
四、总结:
该题的时间复杂度是 O(n) ,这个 n 是链表的长度,因为我们遍历了它,空间复杂度是 O(1) ,我们只引入了常数级别的空间消耗
原题地址:19. 删除链表的倒数第 N 个结点
今天就到这里,学习所得,若有偏差,还请斧正
欢迎点赞,关注,收藏
朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力
好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是阿兵云原生,欢迎点赞关注收藏,下次见~