OJ - 75 對0,1,2進行排序(Sort Color)
阿新 • • 發佈:2018-11-26
題目:給定一個數組,數組裡面的元素取值為:[0, 2],把這個陣列排序。
1.第一種做法:計數排序,因為數組裡面的元素都是正數,可以直接索引到,所以我們直接可以開一個size為3的陣列,用來儲存0,1,2的個數。最後再直接覆寫原來的陣列即可。
void sortColors(vector<int>& nums) {
vector<int> current(3, 0);
int size = nums.size();
for (int i = 0; i < size; ++i) {
current[nums[i]]++;
}
int start = 0, end = 0;
for (int i = 0; i < 3; ++i) {
end += current[i];
for (int j = start; j < end; ++j) {
nums[j] = i;
}
start += current[i];
}
}
這個演算法的時間複雜度為O(N),空間複雜度為O(max(nums))[考慮到如果輸入不止為0,1,2的時候],這個是計數排序的弊端。
我們最好弄一個只遍歷一遍,並且沒有額外空間的使用的演算法:
我們使用三個指標來幫助我們標記當前的元素:i代表遍歷陣列的指標,j代表下一個0元素該出現的地方,k表示下一個2元素該出現的地方。然後我們遍歷這個陣列:噹噹前的元素為0的時候,交換i和j指標的數。並且讓j自增,噹噹前元素為2的時候,交換i和k指標的數,並且讓k自減,i自減,i自減的目的是:不知道交換過來的數到底是幾,所以需要重新判斷。
為什麼1不用判斷:因為我們處理了0和2,放在中間的1自然就有序了,不用處理。所以我們可以有下面的程式碼:
void sortColors(vector<int>& nums) {
int k = nums.size() - 1;
int j = 0;
for (int i = 0; i <= k; i++) {
if (nums[i] == 0) {
swap(nums[i], nums[j++]);
} else if (nums[i] == 2) {
swap(nums[i--], nums[k--]);
}
}
}
void swap(int& a, int& b) {
int c = b;
b = a;
a = c;
}