題目
給定一個包含紅色、白色和藍色,一共 n
個元素的數組,原地對它們進行排序,使得相同顏色的元素相鄰,並按照紅色、白色、藍色順序排列。
此題中,我們使用整數 0
、 1
和 2
分別表示紅色、白色和藍色。
示例:
輸入: [2,0,2,1,1,0]
輸出: [0,0,1,1,2,2]
函數原型
C
的函數原型:
void sortColors(int* nums, int numsSize){}
邊界判斷
void sortColors(int* nums, int numsSize)
{
if( nums == NULL || numsSize == 0 )
return;
}
算法設計:快速排序
思想:先完成再優化,快排即可。
int cmp(const void *a,const void *b)
{
return *(int *)a - *(int *)b;
}
void sortColors(int* nums, int numsSize)
{
if( nums == NULL || numsSize == 0 )
return;
qsort(nums, numsSize, sizeof(int),cmp);
}
- 時間複雜度:
- 空間複雜度:
算法設計:計數排序
思路:使用計數排序的兩趟掃描算法。
- 迭代計算出
0
、1
和2
元素的個數,而後按照0
、1
、2
的排序 - 重寫當前數組
void sortColors(int* nums, int numsSize)
{
if( nums == NULL || numsSize == 0 )
return;
int red=0, white=0, blue=0, i;
for(i=0; i<numsSize; i++)
switch(nums[i]){
case 0: red++; break;
case 1: white++; break;
case 2: blue++;
}
for(i=0; i<red; i++) nums[i]=0;
for(i=red; i<red+white; i++) nums[i]=1;
for(i=red+white; i<numsSize; i++) nums[i]=2;
}
- 時間複雜度:
- 空間複雜度:
算法設計:快排中位數思路+三指針
計數排序遍歷了倆次,其實可用一次搞定。
思路:參考了快速排序的中位數思想,快速排序首先要確定一個待分割的元素做中間點 ,然後把所有小於等於 的元素放到 的左邊,大於 的元素放到其右邊。
目標是這樣:
假設初始是這樣:
定義三個指針:zero
、i
、two
- 所有在子區間 的元素都等於 ;
- 所有在子區間 的元素都等於 ;
- 所有在子區間 的元素都等於 。
當遍歷到某一元素 e
時:
e
有三種情況:
i++
即可,把 納入到
取出 two
前一個元素(暫時這個元素不知道是什麼),與 2
交換即可。
而後 two--
,把 納入到
要找到 zero+1
這個元素,一定是
而後交換 zero+1
和 i
而後 zero++
,把 納入到 ,
相應的 i++
,看下一個元素:
不停的循環…就會排好序。
完整代碼:
void swap(int * a, int * b){
int tmp = *a;
*a = *b;
*b = tmp;
}
void sortColors(int* nums, int numsSize){
/* 三指針 一趟掃描 類似三路快排的partition */
int * left = nums;
int * cur = nums;
int * right = nums + numsSize - 1;
while(cur <= right){
if(*cur == 0){
swap(left, cur);
cur ++;
left ++;
}else if(*cur == 1){
cur ++;
}else{
swap(cur, right);
right --;
}
}
return nums;
}
- 時間複雜度:
- 空間複雜度: