【連結串列問題】刪除單連結串列的中間節點

苦逼的碼農發表於2018-11-29

前言

以專題的形式更新刷題貼,歡迎跟我一起學習刷題,相信我,你的堅持,絕對會有意想不到的收穫。每道題會提供簡單的解答,如果你有更優雅的做法,歡迎提供指點,謝謝。

【題目描述】

給定連結串列的頭節點head,實現刪除連結串列的中間節點的函式。

  例如:

  步刪除任何節點;

  1->2,刪除節點1;

  1->2->3,刪除節點2;

  1->2->3->4,刪除節點2;

  1->2->3->4-5,刪除節點3;

【要求】

如果連結串列的長度為 N, 時間複雜度達到 O(N), 額外空間複雜度達到 O(1)

【難度】

士:★☆☆☆

【解答】

這道題要求刪除中間節點,我們可以採用雙指標的方法來做,就是用一個快指標和一個慢指標,快指標每次前進兩個節點,而慢指標每次前進一個節點。當快指標遍歷完節點時,慢指標剛好就在中間節點了。之前寫過一篇一些常用的演算法技巧總結也有所過指標使用的一些技巧。

不過在做的時候,最好是先把一些特殊情況先處理好,例如刪除的可能是第一個節點,也有可能不用刪除節點(只有一個節點時就不用刪除了。

程式碼如下

    public static Node removeMidNode(Node head) {
        if(head == null || head.next == null)
            return head;
        if (head.next.next == null) {
            return head.next;
        }
        Node fast = head.next.next;//快指標
        Node slow = head;//慢指標

        //slow最終指向中間節點的前驅
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        //進行刪除
        slow.next = slow.next.next;
        return head;
    }

上次那道刪除倒數第 K 個節點的題(【連結串列問題】刪除單連結串列中的第K個節點) 其實也是可以使用雙指標的,但個人認為,那道題使用雙指標的方法並沒有我上次那個做法優雅,而這次刪除中間節點,則用雙指標比較優雅。至於原因,可以自己打下程式碼看看。


之所以說這個事,是因為有人跟我題雙指標的建議,我是非常歡迎有人給我提建議的,不過你的建議如何。不過一上來就說我那篇文章太敷衍,我也是醉了。我開頭已經說了,只提供簡單的解答,而且也把刷題的文章放到次條了。

問題擴充

題目:刪除連結串列中 a / b 處的節點

【題目描述】

  給定連結串列的頭節點 head、整數 a 和 b,實現刪除位於 a/b 處節點的函式。

  例如:

  連結串列:1->2->3->4->5,假設 a/b 的值為 r。

  如果 r = 0,不刪除任何節點;

  如果 r 在區間 (0,1/5] 上,刪除節點 1;

  如果 r 在區間 (1/5,2/5] 上,刪除節點 2;

  如果 r 在區間 (2/5,3/5] 上,刪除節點 3;

  如果 r 在區間 (3/5,4/5] 上,刪除節點 4;

  如果 r 在區間 (4/5,1] 上,刪除節點 5;

  如果 r 大於 1,不刪除任何節點。

【要求】

如果連結串列的長度為 N, 時間複雜度達到 O(N), 額外空間複雜度達到 O(1)

【難度】

士:★☆☆☆

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31561266/viewspace-2222095/,如需轉載,請註明出處,否則將追究法律責任。

相關文章