顏色分類(LintCode)

顏色分類

給定一個包含紅,白,藍且長度爲n的數組,將數組元素進行分類使相同顏色的元素相鄰,並按照紅、白、藍的順序進行排序。

咱們能夠使用整數0,1和2分別表明紅,白,藍。算法

樣例
 
注意

不能使用代碼庫中的排序函數來解決這個問題數組

說明

一個至關直接的解決方案是使用計數排序掃描2遍的算法。ide

首先,迭代數組計算0,1,2出現的次數,而後依次用0,1,2出現的次數去覆蓋數組。函數

你否能想出一個僅使用常數級額外空間複雜度且只掃描遍歷一遍數組的算法?spa

 

代碼寫的亂糟糟的,可貴寫了註釋。code

想法就是把0交換至左邊,2交換至右邊。blog

 1 class Solution {
 2     //總耗時: 14896 ms
 3     
 4     /**
 5      * @param nums: A list of integer which is 0, 1 or 2 
 6      * @return: nothing
 7      */
 8     public void sortColors(int[] nums) {
 9         int low = 0;
10         int high = nums.length-1;
11         //先找到最左的非0和最右的非2
12         while(nums[low] == 0 && low < high) low++;
13         while(nums[high] == 2 && low < high) high--;
14 
15         while(nums[low] == 2 || nums[high] == 0 && low < high) {
16             //若是最左非0是2或者最右非2是0,則將其換至右邊或左邊
17             if(nums[low] == 2) {
18                 if(nums[high] == 0) {
19                     nums[low++] = 0;
20                     nums[high--] = 2;
21                 }else {
22                     nums[high--] = 2;
23                     nums[low] = 1;
24                 }
25             }else {
26                 if(nums[high] == 0) {
27                     nums[low++] = 0;
28                     nums[high] = 1;
29                 }
30             }
31             //找到最左的非0和最右的非2
32             while(nums[low] == 0 && low < high) low++;
33             while(nums[high] == 2 && low < high) high--;
34         }
35         
36         for(int i=low+1;i<high && low < high;i++) {
37             //此時最左非0和最右非2都是1,用i找到0或2,交換到左端或右端
38             if(nums[i] == 0) {
39                 nums[low++] = 0;
40                 nums[i] = 1;
41             }else {
42                 if(nums[i] == 2) {
43                     nums[high--] = 2;
44                     nums[i] = 1;
45                 }
46             }
47             
48             //找到最左的非0和最右的非2
49             while(nums[low] == 0 && low < high) low++;
50             while(nums[high] == 2 && low < high) high--;
51             
52             while(nums[low] == 2 || nums[high] == 0 && low < high) {
53                 //若是最左非0是2或者最右非2是0,則將其換至右邊或左邊
54                 if(nums[low] == 2) {
55                     if(nums[high] == 0) {
56                         nums[low++] = 0;
57                         nums[high--] = 2;
58                     }else {
59                         nums[high--] = 2;
60                         nums[low] = 1;
61                     }
62                 }else {
63                     if(nums[high] == 0) {
64                         nums[low++] = 0;
65                         nums[high] = 1;
66                     }
67                 }
68                 //找到最左的非0和最右的非2
69                 while(nums[low] == 0 && low < high) low++;
70                 while(nums[high] == 2 && low < high) high--;
71             }
72             //若此時的low>=i,顯然要從新設置i
73             if(i <= low) i = low+1;
74         }
75         //當上面的循環結束時,分類就已完成,只遍歷了一次nums,輔助空間爲常數
76     }
77 }
View Code
相關文章
相關標籤/搜索