前言
以專題的形式更新刷題貼,歡迎跟我一起學習刷題,相信我,你的堅持,絕對會有意想不到的收穫。每道題會提供簡單的解答,如果你有更優雅的做法,歡迎提供指點,謝謝。
注:如果程式碼排版出現了問題麻煩通知我下,謝謝。
【題目描述】
給定一個單向連結串列的頭結點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;
}
問題擴充
思考:如果給你的是一個環形連結串列,讓你來劃分,又該如何實現呢?
【題目描述】
無
【要求】
無
【難度】
未知。
【解答】
無。
往期
最後推廣下我的公眾號:苦逼的碼農,文章都會首發於我的公眾號,期待各路英雄的關注交流。