26. 删除有序数组中的重复项(中等)

77 阅读1分钟

题目描述

给你一个链表,删除链表的倒数第 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]

思路分析

  • 之前应该是做过类似的题目,想到的就是快慢指针,快指针先走n步,然后快慢两个指针一起往前走。一次遍历即可。
  • 然后也可以利用栈,先全压入栈,然后pop出第n个节点
  • 然后最容易想到的,先遍历一遍总长度len。然后遍历删除第 len - n 个节点
  • 以上三种方法的时间复杂度应该都是一样的,O(L),L是链表长度

AC代码

// 执行用时:0 ms, 在所有 Go 提交中击败了100.00%的用户
// 内存消耗:2.2 MB, 在所有 Go 提交中击败了100.00%的用户
func removeNthFromEnd(head *ListNode, n int) *ListNode {
    if head == nil || head.Next == nil{
        return nil
    }

    dummy := &ListNode{0, head}
    quick, slow := head, dummy

    for quick != nil {
        if n > 0 {
            quick = quick.Next
            n--
            continue
        }
        quick = quick.Next
        slow = slow.Next
    }

    slow.Next = slow.Next.Next
    return dummy.Next
}

总结

  • 这道题有一个很实用的收获:dummyNode(傻节点、虚拟节点)。它指向head,这样链表中所有的节点都可以用统一的逻辑处理,不用考虑头结点没有前驱节点的特殊处理。很方便。