这是链表的第三篇算法,力扣链接。
给你一个链表,删除链表的倒数第
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 := result
for i := 0; i < length-n; i++ {
cur = cur.Next
}
cur.Next = cur.Next.Next
return result.Next
}
当然也可以考虑空间换时间的思路,即栈的思路解决这个问题,Go没有原生的栈的支持,所以这里考虑用数组来代替。
func removeNthFromEnd(head *ListNode, n int) *ListNode {
stack := make([]*ListNode, 0)
head = &ListNode{
Next: head,
}
result := head
for 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, head
for i := 0; i < n; i++ {
right = right.Next
}
for right != nil {
left = left.Next
right = right.Next
}
left.Next = left.Next.Next
return result.Next
}