刷题使我快乐,满脸开心.jpg
- 来源:力扣(LeetCode)
- 链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/
- 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题目
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
提示:
- 链表中结点的数目为
sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
进阶:你能尝试使用一趟扫描实现吗?
思路
默认进阶属于题目要求的一部分~
1、最直接的思路应该是,用数组也好、栈也好,辅助找到并记录倒n
的位置,然后摘掉倒n
节点即可。不过这样空间复杂度会是O(n)
2、而往往链表问题都能找到空间复杂度的优化方法
比如,常见思路,快慢指针
这道题明显是可以用的,因为快慢指针的快与慢的逻辑定义是可以固定的
,即慢指针比快指针慢n步
那就让快指针先走n步
不过有一点是要注意:
要删除
倒n
节点,慢指针需要指向倒n
节点的前一个节点
我尝试了用慢指针从原链表头开始的处理方式,发现会有各种极端情况影响处理,所以不如在链表头之前再加一个辅助节点。这样慢指针的定义,就变成了指向倒n节点的前一个节点
至此,上代码
代码
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func removeNthFromEnd(head *ListNode, n int) *ListNode {
veryHead := &ListNode{Next: head}
fast := head
slow := veryHead
for n > 0 {
fast = fast.Next
n--
}
// 没到头则slow跟随走动
// fast停下时
// slow的下一个节点就是要去除的节点
for fast != nil {
fast = fast.Next
slow = slow.Next
}
slow.Next = slow.Next.Next
return veryHead.Next
}