题目描述
给你一个链表,删除链表的倒数第 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]
思路分析
- 之前应该是做过类似的题目,想到的就是快慢指针,快指针先走n步,然后快慢两个指针一起往前走。一次遍历即可。
- 然后也可以利用栈,先全压入栈,然后pop出第n个节点
- 然后最容易想到的,先遍历一遍总长度len。然后遍历删除第 len - n 个节点
- 以上三种方法的时间复杂度应该都是一样的,O(L),L是链表长度
AC代码
// 执行用时:0 ms, 在所有 Go 提交中击败了100.00%的用户
// 内存消耗:2.2 MB, 在所有 Go 提交中击败了100.00%的用户
func removeNthFromEnd(head *ListNode, n int) *ListNode {
if head == nil || head.Next == nil{
return nil
}
dummy := &ListNode{0, head}
quick, slow := head, dummy
for quick != nil {
if n > 0 {
quick = quick.Next
n--
continue
}
quick = quick.Next
slow = slow.Next
}
slow.Next = slow.Next.Next
return dummy.Next
}
总结
- 这道题有一个很实用的收获:dummyNode(傻节点、虚拟节点)。它指向head,这样链表中所有的节点都可以用统一的逻辑处理,不用考虑头结点没有前驱节点的特殊处理。很方便。