这是链表的第三篇算法,力扣链接。
给你一个链表,删除链表的倒数第
n
个结点,并且返回链表的头结点。示例 1:
输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5]示例 2:
输入:head = [1], n = 1 输出:[]示例 3:
输入:head = [1,2], n = 1 输出:[1]
老规矩,先上个暴力法来解决问题,暴力法的思路就是先获取链表长度,然后根据长度来判断改变的位置。
func getLength(head *ListNode) (length int) {for ; head != nil; head = head.Next {length++}return
}func removeNthFromEnd(head *ListNode, n int) *ListNode {length := getLength(head)result := &ListNode{0, head}cur := resultfor i := 0; i < length-n; i++ {cur = cur.Next}cur.Next = cur.Next.Nextreturn result.Next
}
当然也可以考虑空间换时间的思路,即栈的思路解决这个问题,Go没有原生的栈的支持,所以这里考虑用数组来代替。
func removeNthFromEnd(head *ListNode, n int) *ListNode {stack := make([]*ListNode, 0)head = &ListNode{Next: head,}result := headfor head != nil {stack = append(stack, head)head = head.Next}if len(stack) > 1 {stack[len(stack)-1-n].Next = stack[len(stack)-1-n].Next.Next}return result.Next
}
当然也可以考虑快慢指针解决这个问题,指针的速度差就是n。
func removeNthFromEnd(head *ListNode, n int) *ListNode {result := &ListNode{Next: head,}left, right := result, headfor i := 0; i < n; i++ {right = right.Next}for right != nil {left = left.Nextright = right.Next}left.Next = left.Next.Nextreturn result.Next
}