思路&代码
给定一个练表,但是未知练表的长度,如何确定倒数第n位置是关键,采用快慢指针同步法,快指针先走n步,之后快慢指针同步移动
当快指针走到末尾的时候,快慢指针之间距离长相差n,对于当前慢指针的下一个节点就是要删除的倒数第n个节点.
package main
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func (l *ListNode) Display() {
for h := l; h != nil; h = h.Next {
fmt.Println(h.Val)
}
fmt.Println("------------")
}
// 核心思想找到如何确定倒数第n的位置,快慢指针,先让快指针跑上n个位置,之后将快慢指针同时跑,等到快指针的的末尾为nil
// 两个指针之间的距离就是倒数n,并且慢指针的下一个节点就是倒数第n个节点,直接删除即可.
func removeNthFromEnd(head *ListNode, n int) *ListNode {
if head == nil || head.Next == nil {
return nil
}
var p *ListNode
var q *ListNode
p = head
q = head
for i := 0; i < n; i++ {
q = q.Next
}
if q == nil { // 链表长度< n,那么n=2,直接返回末尾节点即可
fmt.Println("qqq")
return head.Next
}
for q.Next != nil {
p = p.Next
q = q.Next
}
p.Next = p.Next.Next
return head
}
func main() {
var head, t *ListNode = nil, nil
for i := 0; i < 2; i++ {
n := &ListNode{
Val: i,
Next: nil,
}
if head == nil {
head = n
t = n
} else {
t.Next = n
t = t.Next
}
}
head.Display()
fmt.Println("++++++++++++++++++++")
removeNthFromEnd(head, 2).Display()
}