タイトル説明
変更タイトルはから取られているオランダの旗問題
、赤、白、青、合計n個の配列の要素、in situでそれらをソートし、同じ色を持つように隣接する素子と、赤、白、青の順に配置所与。
この問題は、我々は、赤、白、青を表す0、1、2の整数を使用します。
注:
あなたがこの質問を解決するためのソート機能のコードベースを使用することはできません。
例:
入力:[2,0,2,1,1,0]
出力:[0,0,1,1,2,2]
アドバンス:
直感的なソリューションは、注文を用いたアルゴリズム二回のスキャンを数えることです。
まず、要素0、1、2、及びその後の数の反復計算は、現在のアレイを上書き、0,1,2ソート。
あなただけの一定のスペースアルゴリズムを使用しない単一のパスを考えることができますか?
出典:滞在ボタン(LeetCode)
リンク:https://leetcode-cn.com/problems/sort-colors
思考
-
ソート数えるが、それはACにできるものの、二回スキャンする必要があるが、質問の規格外の意味。
-
唯一の三色ので、インデックスを記録することができる、インデックスのインデックス、他の2(青)の0(赤)であり、二つのポインタの中央に行きます。我々は、それぞれ記録し、最も左の境界、及び現在のポインタデータ(赤、青、CURR)に3つのポインタ0(赤)、右端の境界、2(青)を使用しました。
右端のボーダーの初期化0:0 =赤。アルゴリズムNUMSの実行を通して[IDX <赤] = 0。
初期左端ボーダー2:青色= N - 1。アルゴリズムNUMSの実行[IDX>青] = 2を通して。
CURR = 0:数を考慮し、現在の要素を初期化します。
CURRながら<=青:
もしNUMS [CURR] = 0番目の要素第一及び第二の赤CURR、右へのポインタを切り替えます。
NUMSなら[CURR] = 2:CURR番目および青色要素の交換、左及び青へのポインタ。
NUMSなら[CURR] = 1:右CURRポインタ。
C ++
// 两趟算法
class Solution {
public:
void sortColors(vector<int>& nums) {
int counts[3] = {0};
for(int i = 0; i < nums.size();++ i){
counts[nums[i]] ++;
}
for(int i = 0, index = 0; i < 3;++ i){
for(int j = 0; j < counts[i]; ++ j)
nums[index ++] = i;
}
}
};
// 双指针
class Solution {
public:
/*
荷兰三色旗问题解
*/
void sortColors(vector<int>& nums) {
int red = 0, curr = 0;
int blue = nums.size() - 1;
while (curr <= blue) {
if (nums[curr] == 0) {
swap(nums[curr++], nums[red++]);
}
else if (nums[curr] == 2) {
swap(nums[curr], nums[blue--]);
}
else curr++;
}
}
};