leetcode-75-sort colors
阿新 • • 發佈:2019-02-09
問題
思路
我們可以把陣列分成三部分,前部(全部是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;
}
};