【連結串列問題】打卡7:將單向連結串列按某值劃分成左邊小,中間相等,右邊大的形式

帥地發表於2019-02-24

前言

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

注:如果程式碼排版出現了問題麻煩通知我下,謝謝。

【題目描述】

給定一個單向連結串列的頭結點head,節點的值型別是整型,再給定一個整數privot。實現一個調整連結串列的函式,將連結串列調整為左部分都是值小於privot的節點,中間部分都是值等於privot的節點,右部分都是大於privot的節點。且對某部分內部節點的順序不做要求

例如:連結串列9-0-4-5-1,pivot=3。

調整後是1-0-4-9-5,

也可以是0-1-9-5-4

【要求】

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

【難度】

尉:★★☆☆

【解答】

這道題在思路上還是比較簡單的,但是在實現上還是有一些細節需要主要的。

本題對某部分的內部節點不做要求,一種很簡單的方法就是用一個陣列來存連結串列的節點,然後像類似於快速排序的分割函式那樣,按照某個值把他們進行劃分。

不過這樣做的話,空間複雜度為 O(N)。我們也可以採取使用3個指標,把原連結串列依次劃分成三個部分的連結串列,然後再把他們合併起來,這種做法不但空間複雜度為 O(1), 而且內部節點的順序也是和原連結串列一樣的。雖然思路簡單,但在程式碼實現上也是有很多細節需要注意的,有時間的話希望大家動手打下碼。

程式碼如下

    //用三個指標處理,這道題主要是要注意串聯連結串列時的一些細節處理
    public static Node listPartition(Node head, int pivot) {
        Node sB = null;//小的指標頭,即small begin
        Node sE = null;//小的指標尾,即 small end
        Node eB = null;//中的指標頭,即 equal begin
        Node eE = null;//中的指標尾,即emall end
        Node bB = null;//大的指標頭,即 big begin
        Node bE = null;//大的指標尾,即 big end
        Node next = null;//儲存下一個節點
        //進行劃分
        while (head != null) {
            next = head.next;
            head.next = null;
            if (head.value < pivot) {
                if (sB == null) {
                    sB = head;
                    sE = head;
                } else {
                    sE.next = head;
                    sE = sE.next;
                }
            } else if (head.value == pivot) {
                if (eB == null) {
                    eB = head;
                    eE = head;
                } else {
                    eE.next = head;
                    eE = eE.next;
                }
            } else {
                if (bB == null) {
                    bB = head;
                    bE = head;
                } else {
                    bE.next = head;
                    bE = bE.next;
                }
            }
            head = next;
        }
        //把三部分串連起來,串聯的時候細節還是挺多的,
        //串聯的過程下面程式碼的精簡程度是最學習的部分了
        
        //1.小的與中的串聯
        if (sB != null) {
            sE.next = eB;
            eE = eE == null ? sE : eE;
        }
        //2.中的和大的連線
        if (eB != null) {
            eE.next = bB;
        }
        return sB != null ? sB : eB != null ? eB : bB;
    }

問題擴充

思考:如果給你的是一個環形連結串列,讓你來劃分,又該如何實現呢?

【題目描述】

【要求】

【難度】

未知。

【解答】

無。

往期

【連結串列問題】打卡6:三種方法帶你優雅判斷迴文連結串列

【連結串列問題】環形單連結串列約瑟夫問題

【連結串列問題】如何優雅著反轉單連結串列

最後推廣下我的公眾號:苦逼的碼農,文章都會首發於我的公眾號,期待各路英雄的關注交流。

相關文章