荷蘭國旗問題引出的三色排序

風是甜的你是我的發表於2018-07-16

現在有若干個紅、白、藍三種顏色的球隨機排列成一條直線。現在我們的任務是把這些球按照紅、白、藍排序,就類似於荷蘭國旗一樣。

這個問題我們可以將這個問題視為一個陣列排序問題,這個陣列分為前部,中部和後部三個部分,每一個元素(紅白藍分別對應0、1、2)必屬於其中之一。

由於紅、白、藍三色小球數量並不一定相同,所以這個三個區域不一定是等分的,也就是說如果我們將整個區域放在[0,1]的區域裡,由於三色小球之間數量的比不同(此處假設1:2:2),可能前部為[0,0.2),中部為[0.2,0.6),後部為[0.6,1]。我們的思路如下:將前部和後部各排在陣列的前邊和後邊,中部自然就排好了。

具體方法如下:

設定兩個標誌位begin和end分別指向這個陣列的開始和末尾,然後用一個標誌位i從頭開始進行遍歷:
1)若遍歷到的位置為0,則說明它一定屬於前部,於是就和begin位置進行交換,然後i向前進,begin也向前進(表示前邊的已經都排好了)。
2)若遍歷到的位置為1,則說明它一定屬於中部,根據總思路,中部的我們都不動,然後i向前進。

3)若遍歷到的位置為2,則說明它一定屬於後部,於是就和end位置進行交換,由於交換完畢後i指向的可能是屬於前部的,若此時i前進則會導致該位置不能被交換到前部,所以此時i不前進。而同1),end向前進一。

具體程式碼如下:

class Solution {
public:
    void sortColors(int A[], int n) {
        int begin = 0;
        int end = n-1;
        int i = 0;
        while(i<end+1)
        {
            if(A[i]==0)
            {
                swap(A[i], A[begin]);
                begin++;
                i++;
            }
            else if(A[i]==2)
            {
                swap(A[i], A[end]);
                end--;
                //i++;
            }
            else
                i++;
        }
    }
};

相關文章