19. 删除链表的倒数第 N 个结点 #
题目地址 #
解题思路 #
常规法 #
先计算链表长度,比如是 length。那么删除倒数第 n 个节点,也就是删除顺数第 length-n+1 个节点,设为 s,直接从 1 找到第 s-1 个也就是 s 的上一个节点(其实也就是 length-n),直接把 s-1 删除即可。
双指针法 #
TODO
具体实现 #
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func removeNthFromEnd(head *ListNode, n int) *ListNode {
if head == nil {
return head
}
length := 0
tmpc := head
for tmpc != nil {
//fmt.Println(tmpc.Val)
length++
tmpc = tmpc.Next
}
// 需要有虚拟头结点是因为,可能删除的是最后的节点,也就是头结点,用虚拟头结点可以统一处理
dummy := &ListNode{
Val: 0,
Next: head,
}
cur := dummy
// 注意这里 i 是从 1 开始
for i := 1; i < length-n+1; i++ {
cur = cur.Next
}
cur.Next = cur.Next.Next
return dummy.Next
}
func main() {
ret := removeNthFromEnd(&ListNode{
Val: 1,
Next: &ListNode{
Val: 2,
Next: &ListNode{
Val: 3,
Next: &ListNode{
Val: 4,
Next: &ListNode{
Val: 5,
Next: nil,
},
},
},
},
}, 2)
fmt.Println(ret)
}
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func removeNthFromEnd(head *ListNode, n int) *ListNode {
if head == nil {
return head
}
dummy := &ListNode{
Next: head,
}
fast, low := dummy, dummy
// fast 先移动 n 步
for n != 0 && fast != nil {
fast = fast.Next
n--
}
// fast 再移动一步,这样当 fast 为 nil 时,low 在 n 的上一位
fast = fast.Next
for fast != nil {
fast = fast.Next
low = low.Next
}
low.Next = low.Next.Next
return dummy.Next
}
func main() {
ret := removeNthFromEnd(&ListNode{
Val: 1,
Next: &ListNode{
Val: 2,
Next: &ListNode{
Val: 3,
Next: &ListNode{
Val: 4,
Next: &ListNode{
Val: 5,
Next: nil,
},
},
},
},
}, 2)
fmt.Println(ret)
}