删除链表的倒数第 n 个结点

8 阅读1分钟

删除链表的倒数第 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
}