給定乙個包含紅色、白色和藍色,一共 n 個元素的陣列,原地對它們進行排序,使得相同顏色的元素相鄰,並按照紅色、白色、藍色順序排列。
此題中,我們使用整數 0、 1 和 2 分別表示紅色、白色和藍色。
注意:不能使用**庫中的排序函式來解決這道題。
示例:
輸入: [2,0,2,1,1,0]
輸出: [0,0,1,1,2,2]
思路分析:這是一道非常經典的三色旗排序問題。由於顏色是使用數字進行表示,所以可以使用排序演算法將它們從小到大排列即可。並且由於數字的種類只用三種,所以可以使用「計數排序」演算法進行實現。(這裡只介紹計數排序,其他排序思路一樣)
「計數排序」:簡單的說就是記錄待排序陣列中的每種元素出現的次數,然後依照需要的順序重寫陣列即可。(時間複雜度為o(n),額外的空間複雜度為o(n))
演算法實現:
class
solution
//對nums進行重寫
方法二:使用使用三個指標進行掃瞄,一趟完成排序。
class
solution
if(red >= numssize -1)
while
(blue >=
0&& nums[blue]==2
)if(blue <=0)
white = red +1;
//定位白色旗指標
三指標演算法優化,不難發現,紅色指標red的作用是保證red下標前都是紅色旗,藍色指標blue的作用是保證blue下標後都是藍色旗,white指標的作用是將中間不是白色的旗放到兩邊。則退出while迴圈時red、blue至少有乙個指向白色旗,如果兩個之中有乙個不是白色旗則需要進行掉換(示例單步執行就是這種情況,可以試試)。
class
solution
int red =0;
//紅色旗掃瞄指標(從前往後
int blue = numssize -1;
//藍色旗掃瞄指標(從後往前
int white = red +1;
//定位白色旗指標,從中間往後
while
(white <= blue)
if(nums[red]==2
&& nums[blue]==0
)else
if(nums[white]==0
)else
if(nums[white]==2
)while
(red < numssize && nums[red]==0
)while
(blue >=
0&& nums[blue]==2
)if(white <= red)
}//最後需要將紅色指標與藍色指標交換
根據三個指標的功能進行分析,三指標再優化就是三路快排了。
class
solution
else
if(nums[white]==1
)else}}
};
三指標掃瞄的演算法最好在紙上執行一下示例(或者在ide中單步執行),理下思路。 三路快排 75 顏色分類
給定乙個包含紅色 白色和藍色,一共 n 個元素的陣列,原地對它們進行排序,使得相同顏色的元素相鄰,並按照紅色 白色 藍色順序排列。此題中,我們使用整數 0 1 和 2 分別表示紅色 白色和藍色。注意 不能使用 庫中的排序函式來解決這道題。示例 輸入 2,0,2,1,1,0 輸出 0,0,1,1,2,...
三路快排板子
還是覺得別人的快排寫得太醜了 雙路快排 void qsort2 int l,int r 隨機取值 int index rand r l 1 l swap nums l nums index int key nums l int i l,j r while i j nums i nums j whil...
快速排序之三路快排
當大量出現重複值時,我們使用三路快排,如下 arr 表示排序陣列 l 表示陣列左邊界 r 表示陣列右邊界 public static void quicksortinternal3 int arr,int l,int r else if arr i v else 交換l與lt元素,可以確定基準值的位...