这是 LeetCode 第 19 题 ,刚好在看 labuladong 的算法书看到这个双指针的解法,非常巧妙。
func removeNthFromEnd(head *ListNode, n int) *ListNode {
s, in, inpre := head, head, head // `哨兵`先探路,`步兵`随其后,`步兵上把手`要记录`步兵`位置
// `哨兵`先走 n 步
for i := 0; i < n; i++ {
s = s.Next
}
// `哨兵`和`步兵`一起前进,直到`哨兵`到头,`步兵上把手`要一直记录`步兵`位置
for s != nil {
s = s.Next
inpre = in
in = in.Next
}
// `步兵`还在头部位置没有前进,删除头结点
if in == head {
return head.Next
}
// 删除此`步兵`位置,将`步兵上把手`的 next 地址指向`步兵`的 next 地址
inpre.Next = in.Next
return head
}
核心思路在于让前面的指针前进 N 步,然后两个指针共同前进,当先前进的指针到头的时候,后面的位置刚好是倒数第 N 个节点。