時間:2014.08.07
地點:基地
----------------------------------------------------------------------------------
一、題目描述
現有紅白藍三個不同顏色的小球,亂序排列在一起,重新排列這些小球,使得紅白藍三色的同顏色的球在一起。這個問題之即荷蘭國旗問題,將紅白藍三色小球想象成條狀物,有序排列後正好組成荷蘭國旗。如下圖所示:
----------------------------------------------------------------------------------
二、思路
2.1方法一:排序
若是把顏色與數值對應起來,其實是個簡單的排序問題,只不過元素取值只含3個,且有重複,不妨設爲0 1 2 ,
於是採用各種排序都可解決。時間複雜度對於各種排序方法對應的時間複雜度。
2.2方法二:劃分
將元素劃分成三個部分,思路:
2.2.1 設置三個指針begin current end,begin current初始化指向數組首元素,end初始化指向數組尾元素
2.2.2 檢查current指向的值,爲 0 :則與begin交換值,然後current begin均後移一個位置
爲1 :則begin不動,current後移一個位置
爲2:則與end交換值,然後current後移一個位置,end前移一個位置
2.2.3重複上述過程,當current>end時停止,注意這裏的條件不可以取等於(比如在序列中如果存在連續的 2 0,恰好current指向2,end指向0,則交換後爲0 2,而這之前可能還有1,此時還不能終止重複過程。時間複雜符爲O(n)
代碼如下:
//荷蘭國旗問題2014.08.07
#include<iostream>
#include<vector>
#include<algorithm>
void Partition(std::vector<int>& vec)
{
auto begin = vec.begin();
auto end = vec.end() - 1;
auto cursor = begin;
while (cursor <= end)
{
if (0 == *cursor)
{
std::swap(*cursor, *begin);
++begin;
++cursor;
}
else if (1 == *cursor)
++cursor;
else
{
std::swap(*cursor, *end);
--end;
}
}
}
int main()
{
std::vector<int> vec{0, 1, 1,1,2,0,2,1,0, 2, 0, 2 };
Partition(vec);
for (auto element : vec)
std::cout << element << ' ';
std::cout << std::endl;
}