删除链表的倒数第 n 个结点
思路一
先算出链表的元素个数,判断删除的是正数第几个结点
用两个指针向前移动,移动到这个位置时,删除这个结点。
func removeNthFromEnd(head *ListNode, n int) *ListNode {
p := head
count := 1
for p.Next != nil {
p = p.Next
count++
}
//正数的第几个结点
nPositive := count - n + 1
cur := head
pre := &ListNode{
Next: cur,
}
//注意,头结点可能被删除
result := pre
count = 1
for count < nPositive {
cur = cur.Next
pre = pre.Next
count++
}
//把cur节点删除
pre.Next = cur.Next
return result.Next
}
优化,可以用一个指针移动,到时候删除结点时,令 p.Next=p.Next.Next 这样的写法即可
func removeNthFromEnd(head *ListNode, n int) *ListNode {
p := head
count := 1
for p.Next != nil {
p = p.Next
count++
}
//正数的第几个结点
nPositive := count - n + 1
pre := &ListNode{
Next: head,
}
//注意,头结点可能被删除
result := pre
count = 1
for count < nPositive {
pre = pre.Next
count++
}
//把cur节点删除
pre.Next = pre.Next.Next
return result.Next
}
思路二
快慢指针法,来找到倒数第 n 个结点
func removeNthFromEnd(head *ListNode, n int) *ListNode {
dummp := &ListNode{
Next: head,
}
slow, fast := dummp, dummp
//fast先走n+1步,注意不是走n步
for i := 0; i <= n; i++ {
fast = fast.Next
}
//fast和slow同时走,直到fast到达末尾
for fast != nil {
slow = slow.Next
fast = fast.Next
}
slow.Next=slow.Next.Next
return dummp.Next
}