leetcode[75] sort colors

給定一個數組,有0,1,2三個數,把數組排好序。不能直接用sort。html

策略一:數組

簡單的思路,掃描兩次,第一次記錄0,1,2的個數,第二次重寫數組。spa

class Solution {
public:
    void sortColors(int A[], int n) {
        if(n < 2) return ;
        int n0 = 0, n1 = 0, n2 = 0;
        vector<int> ans(n);
        for (int j = 0; j < n; j++)
        {
            if (A[j] == 0) n0++;
            else if (A[j] == 1) n1++;
            else n2++;
        }
        int i = 0;
        while(i < n0) {A[i] = 0;i++;}
        while(i < n0 + n1) {A[i] = 1;i++;}
        while(i < n0 + n1 + n2) {A[i] = 2;i++;}
        return ;
    }
};

但,要求只掃描一次,常數空間。指針

策略二:code

定義一個left,一個righthtm

1. 遇到1,left++blog

2. 遇到2,和right位置換排序

3. 遇到0,往前和第一個非零數字換,left++索引

class Solution {
public:
    void sortColors(int A[], int n) {
        int left = 0, right = n -1;
        while(left <= right)
        {
            if (A[left] == 0)
            {
                int index = left - 1;
                while(index >= 0 && A[index] != 0) index--; // 這個算掃描一次嗎?
                if (index < 0)
                    swap(A[0], A[left]);
                else
                    swap(A[index+1], A[left]);
                left++;
            }
            else if (A[left] == 1)
                ++left;
            else if (A[left] == 2)
            {
                swap(A[left], A[right]);
                right--;
            }
        }
    }
};

策略三:get

藉助於快速排序的partition思想,以1爲樞紐元對數組進行劃分,使0在數組的左邊,2在數組的右邊,1在數組的中間。

class Solution {
public:
    void sortColors(int A[], int n) {
        //zeroEnd是放0那部分的尾部索引,twoEnd是放2那部分的首部索引
        //碰到0放到zeroEnd+1處,碰到2放到twoEnd-1處,碰到1指針後移
        int zeroEnd = -1, twoBegin = n, i = 0;
        while(i < twoBegin)
        {
            if(A[i] == 0 && i != ++zeroEnd)
                swap(A[zeroEnd], A[i]);
            else if(A[i] == 2 && i != --twoBegin)
                swap(A[twoBegin], A[i]);
            else
                i++;
        }
    }
};

 2015/03/31:

class Solution {
public:
    void sortColors(int A[], int n) {
        if(n <= 1) return;
        int start = 0, end = n - 1;
        int i = 0;
        while(i <= end){
            if(A[i] == 0 && i != start){
                swap(A, start++, i);
            }else if(A[i] == 2 && i != end){
                swap(A, i, end--);
            }else ++i;
        }
    }
private:
    void swap(int A[], int i, int j){
        int temp = A[i];
        A[i] = A[j];
        A[j] = temp;
    }
};
相關文章
相關標籤/搜索