算法面試之道:在O(1)的時間內刪除單連接鏈表的指定節點

具體講解和調試演示,請參看視頻:
如何進入google,算法面試技能全面提高指南node

對於一個單項連接的鏈表,給定其中某個任意節點,要求在O(1)的時間複雜度內刪除該節點。表面上看起來,彷佛不可能作到,由於若是要求時間複雜度是O(1)的話,那意味着,算法實現中,不得包含有任何循環或是對鏈表的總體遍歷。面試

但問題在於,要刪除某個指定節點,咱們須要經過遍歷,找到該節點的前節點,而後修改前節點的next指針,這樣才能正常的刪除當前節點。算法

但若是給定的節點不是鏈表的末尾節點的話,那麼要作到這一點就不難,只須要一點小技巧就能夠實現,因而,問題轉換以下:微信

假設節點v是單項連接鏈表中的某個節點,而且確保v不是鏈表的尾節點,要求在O(1)的時間複雜度內刪除該節點.markdown

例如給定鏈表以下:app

給定的節點v就是值爲3的節點,要求在O(1)的時間內刪除該節點,而且不能使用多餘內存。機器學習

通常作法是找到節點3的前節點,也就是節點2,而後把節點2的next指針指向節點4,但因爲咱們不能從頭遍歷,因此咱們沒法找到節點2.學習

可是咱們可使用個小技巧,把節點4的值拷貝到節點3,而後把節點3的next指針指向節點5,那就能夠了:ui


具體代碼實現以下:google

public class NodeDelete {

    public void deleteNode(Node node) {
        if (node.next == null) {
            return ;
        }

        node.val = node.next.val;
        node.next = node.next.next;
    }
}

主入口處的代碼以下:

public class LinkList {
    public static void main(String[] args) {
        ListUtility util = new ListUtility();
        Node head = util.createList(10);
        System.out.println("Link list before node deletion:");
        util.printList(head);
        Node n = util.getNodeByIdx(head, 3);

        NodeDelete nd = new NodeDelete();
        nd.deleteNode(n);

        System.out.println("Link list after node deletion: ");
        util.printList(head);
    }
}

首先構建一個含有5個節點的單向鏈表,而後得到值爲3的節點,先把節點刪除前的鏈表打印出來,而後調用算法實現刪除指定節點,最後再把刪除後的鏈表打印出來,運行後結果以下:

Link list before node deletion:
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
Link list after node deletion:
0 -> 1 -> 2 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null

因而可知,咱們的算法實現是正確的,同時在算法實現中,咱們並無使用循環去遍歷隊列,只是對節點的next指針作一些操做,所以算法的時間複雜度確實是O(1).

問題的解法看起來至關簡單,但問題在於,在面試中,你處於一種緊張的壓力狀態之下,同時思考時間有限,有了想法後,還得把代碼寫出來,而且保證代碼不出錯,所以,看似簡單的題目,在有限的時間約束和必定的心理壓力之下,想順利的解決,也不是一件容易的事情。

更多技術信息,包括操做系統,編譯器,面試算法,機器學習,人工智能,請關照個人公衆號:

本文分享自微信公衆號 - Coding迪斯尼(gh_c9f933e7765d)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索