[75].顏色分類

 


題目

給定一個包含紅色、白色和藍色,一共 n 個元素的數組,原地對它們進行排序,使得相同顏色的元素相鄰,並按照紅色、白色、藍色順序排列。

此題中,我們使用整數 012 分別表示紅色、白色和藍色。

示例:

輸入: [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);
}
  • 時間複雜度:Θ(nlogn)\Theta(n*logn)
  • 空間複雜度:Θ(n)\Theta(n)
     

算法設計:計數排序

思路:使用計數排序的兩趟掃描算法。

  • 迭代計算出 012 元素的個數,而後按照 012 的排序
  • 重寫當前數組
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;
}
  • 時間複雜度:Θ(n)\Theta(n)
  • 空間複雜度:Θ(1)\Theta(1)

 


算法設計:快排中位數思路+三指針

計數排序遍歷了倆次,其實可用一次搞定。

思路:參考了快速排序的中位數思想,快速排序首先要確定一個待分割的元素做中間點 xx,然後把所有小於等於 xx 的元素放到 xx 的左邊,大於 xx 的元素放到其右邊。

目標是這樣:


假設初始是這樣:


定義三個指針:zeroitwo

  • 所有在子區間 [0,zero)[0, zero) 的元素都等於 00
  • 所有在子區間 [zero,i)[zero, i) 的元素都等於 11
  • 所有在子區間 [two,len1][two, len - 1] 的元素都等於 22

當遍歷到某一元素 e 時:


e 有三種情況:

  • e=1e = 1

    i++ 即可,把 11 納入到 [zero,i)[zero, i)

  • e=2e = 2

取出 two 前一個元素(暫時這個元素不知道是什麼),與 2 交換即可。


而後 two--,把 22 納入到 [two,len1][two, len - 1]


  • e=0e = 0

要找到 zero+1 這個元素,一定是 11

而後交換 zero+1i

而後 zero++,把 00 納入到 [0,zero)[0, 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;
}
  • 時間複雜度:Θ(n)\Theta(n)
  • 空間複雜度:Θ(1)\Theta(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章