刪除鏈表的倒數第N個節點

題目描述:html

給定一個鏈表,刪除鏈表的倒數第 個節點,而且返回鏈表的頭結點。算法

示例:優化

給定一個鏈表: 1->2->3->4->5, 和 n = 2.

當刪除了倒數第二個節點後,鏈表變爲 1->2->3->5.

說明:spa

給定的 n 保證是有效的。指針

解題思路:code

方法一:兩次遍歷算法

思路htm

咱們注意到這個問題能夠容易地簡化成另外一個問題:刪除從列表開頭數起的第 (L - n + 1)(Ln+1) 個結點,其中 LL 是列表的長度。只要咱們找到列表的長度 LL,這個問題就很容易解決。blog

算法rem

首先咱們將添加一個啞結點做爲輔助,該結點位於列表頭部。啞結點用來簡化某些極端狀況,例如列表中只含有一個結點,或須要刪除列表的頭部。在第一次遍歷中,咱們找出列表的長度 LL。而後設置一個指向啞結點的指針,並移動它遍歷列表,直至它到達第 (L - n)(Ln) 個結點那裏。咱們把第 (L - n)(Ln) 個結點的 next 指針從新連接至第 (L - n + 2)(Ln+2) 個結點,完成這個算法。io

 

方法二:一次遍歷算法

算法

上述算法能夠優化爲只使用一次遍歷。咱們能夠使用兩個指針而不是一個指針。第一個指針從列表的開頭向前移動 n+1n+1 步,而第二個指針將從列表的開頭出發。如今,這兩個指針被 nn 個結點分開。咱們經過同時移動兩個指針向前來保持這個恆定的間隔,直到第一個指針到達最後一個結點。此時第二個指針將指向從最後一個結點數起的第 nn個結點。咱們從新連接第二個指針所引用的結點的 next 指針指向該結點的下下個結點。

class Solution:
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        h = ListNode(-1)
        h.next = head
        p, q = h, h

        for _ in range(n + 1):
            q = q.next

        while q != None:
            p = p.next
            q = q.next

        p.next = p.next.next
        return h.next
相關文章
相關標籤/搜索