funcmain() { h := new(ListNode) p := h for i := 1; i<6; i++ { temp := new(ListNode) temp.Val = i p.Next = temp p = p.Next } printList(h.Next) fmt.Println("-------") ll := removeNthFromEnd(h.Next, 2) printList(ll) }
// 打印链表 funcprintList(head *ListNode) { for i := head; i != nil; i = i.Next { fmt.Println(i.Val) } }
type ListNode struct { Val int Next *ListNode }
/** * 基本策略:双指针,两个指针的间隔为n+1,当后一个指针遍历到链表尾部时,则前一个指针的后面一个元素就是到处第n个元素 */ funcremoveNthFromEnd(head *ListNode, n int) *ListNode { if head == nil { return head }
/** * 最初没有设想到head被删除的所有情况,只想到n=1与链表长度为1的情况, * head被删除的所有情况是:链表长度为n * 在开始纠结了好久删除head的情况:其实额外添加一个节点能让问题简化 */ h := new(ListNode) h.Next = head
/** * 初始化 */ p, tail := h, head /** * 之所以将i不作为临时变量,是通过判断i与tail,判断在tail指针移动n步的过程中,是先tail为空,还是i先为n */ i := 0 for ; i < n && tail != nil; i++ { tail = tail.Next } if tail == nil && i == n { // 即链表长度为n return head.Next } elseif tail == nil && i < n { // 链表长度大于n return head }
/** * 这里的问题:循环终止条件应该是到了尾部 */ for tail != nil { tail = tail.Next p = p.Next }