1. 程式人生 > >leetcode-75-sort colors

leetcode-75-sort colors

問題

思路

我們可以把陣列分成三部分,前部(全部是0),中部(全部是1)和後部(全部是2)三個部分,每一個元素(紅白藍分別對應0、1、2)必屬於其中之一。

將前部和後部各排在陣列的前邊和後邊,中部自然就排好了。

設定兩個指標begin指向前部的末尾的下一個元素(剛開始預設前部無0,所以指向第一個位置),end指向後部開頭的前一個位置(剛開始預設後部無2,所以指向最後一個位置),然後設定一個遍歷指標current,從頭開始進行遍歷。

(1)若遍歷到的位置為1,則說明它一定屬於中部,根據總思路,中部的我們都不動,然後current向前移動一個位置。

(2)若遍歷到的位置為0,則說明它一定屬於前部,於是就和begin位置進行交換,然後current向前移動一個位置,begin也向前移動一個位置(表示前邊的已經都排好了)。

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

這裡面有幾個點需要搞清楚:
1.begin end的意義
2.begin end怎麼初始化
3.為什麼與前部進行了交換,cur++?這是為什麼?

可以這麼考慮:
由於begin < end是肯定的,所以,如果交換之後,需要再次判斷那只有一種可能就是這個元素是2,但是,都已經訪問到cur,前面又怎麼可能存在2。但是,後面的交換是可能的,所以需要再次判斷。

程式碼

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int begin = 0;
        int end = nums.size() - 1;
        int cur = 0;

        while(cur <= end) {
            if( nums[cur] == 1 ) ++cur;
            else if( nums[cur] == 0 ) { swap( nums[begin], nums[cur] ); ++begin; ++cur; }
            else
{ swap( nums[cur], nums[end] ); --end; } } } private: void swap(int& a, int& b) { int t = a; a = b; b = t; } };