演算法學習-荷蘭國旗問題
題目
問題分析現有紅、白、藍三個不同顏色的小球,亂序排列在一起,請重新排列這些小球,使得紅白藍三色的同顏色的球在一起。
問題轉換為:給定陣列A[0...N-1],元素只能取0、1、2三個值,設計演算法,使得陣列排列成“00...0011...1122...22”的形式
借鑑快速排序中partition的過程,定義三個指標begin=0,current=0,end=N-1
A[cur]==2,則A[cur]與A[end]交換,end--,cur不變
A[cur]==1,則cur++,begin不變,end不變
A[cur]==0,則:
若begin==cur,則begin++,cur++
若begin!=cur,則A[cur]與A[begin]交換,begin++,cur不變
程式碼如下
void Holland1(int* a, int length)
{
int begin = 0;
int current = 0;
int end = length - 1;
while (current <= end)
{
if (a[current] == 2)
{
swap(a[end], a[current]);
end--;
}
else if (a[current] == 1)
{
current++;
}
else
{
if (begin == current)
{
begin++;
current++;
}
else
{
swap(a[current], a[begin]);
begin++;
}
}
}
}
第二個版本:
cur掃過的位置,即:[begin,cur)區間內,一定沒有2
因此:A[begin]要麼是0,要麼是1,不可能是2在前面的A[cur]==2中,已經被替換到陣列後面了
考察begin指向的元素的值:
歸納法:若begin!=cur,則必有A[begin]=1
因此,當A[cur]==0時,
若begin==cur,則begin++,cur++;
若begin!=cur,因為A[begin]==1,則交換後,A[cur]==1,此時,可以cur++;
void Holland2(int* a, int length)
{
int begin = 0;
int current = 0;
int end = length - 1;
while (current <= end)
{
if (a[current] == 2)
{
swap(a[end], a[current]);
end--;
}
else if (a[current] == 1)
{
current++;
}
else
{
if (begin == current)
{
begin++;
current++;
}
else
{
swap(a[current], a[begin]);
begin++;
current++;
}
}
}
}
終極版本
void Holland(int* a, int length)
{
int begin = 0;
int current = 0;
int end = length - 1;
while (current <= end)
{
if (a[current] == 2)
{
swap(a[end], a[current]);
end--;
}
else if (a[current] == 1)
{
current++;
}
else
{
if (current != begin)
{
swap(a[current], a[begin]);
}
begin++;
current++;
}
}
}
荷蘭國旗問題擴充套件
- 將0/1/2分別計數,根據三個計數值c0/c1/c2:前c0個元素賦值為0,中間c1個元素賦值為1,最後c2個元素賦值為2;實際意義比較小,可能排序結構比較複雜的時候就用著不方便了
- 將(0,1)(2)根據快速排序的Partition,劃分為兩部分(如PivotKey1.5);將(0)(1)根據快速排序Partition,分成兩部分(如PivotKey選擇0.5);那麼可以得到結論“兩次Partition==一次荷蘭國旗”,這樣可以優化快速排序的Partition過程
優化快速排序根據PivotKey分成大於、小於等於兩部分或者大於等於、小於兩部分
根據PivotKey的大小,將Partition過程蓋在成大於、等於、小於三部分
優點:對於快速排序的等於PivotKey的數值,可以在執行下一次Partition時直接跳過,利於資料規模的降低
相關文章
- 彩虹排序 | 荷蘭旗問題排序
- 荷蘭國旗問題引出的三色排序排序
- 高頻面試考題:荷蘭旗問題面試
- 在連結串列上實現 Partition 以及荷蘭國旗問題
- 迴圈不變數之荷蘭國旗變數
- CTF學習(20)MISC(荷蘭寬頻資料洩露)
- 荷蘭國家統計局:荷蘭特斯拉車主被開超速罰單比例高達75%
- 荷蘭推出國家區塊鏈研究計劃區塊鏈
- 演算法學習回顧-皇后問題演算法
- 荷蘭加密貨幣許可證加密
- 荷蘭伺服器有哪些優勢?荷蘭伺服器又該如何選擇呢?-VeCloud伺服器Cloud
- 【演算法學習筆記】生成樹問題探究演算法筆記
- Dealroom:2021年荷蘭教育科技報告OOM
- 預計2020年荷蘭外國遊客將達2000萬人 超本國人口
- react 學習 問題React
- 恆訊科技介紹:荷蘭Serverius資料中心Server
- 手擼機器學習演算法 - 非線性問題機器學習演算法
- 學習方向的問題
- Spark學習——問題排查Spark
- 面經問題學習
- 荷蘭國際集團:調查顯示38%歐洲人買不起房
- 【演算法工程師】機器學習面試問題總結演算法工程師機器學習面試
- KentekenRadar:特斯拉Model 3成荷蘭最暢銷車型
- 荷蘭法院判決比特幣具有“財產屬性”比特幣
- 荷蘭銀行實施大規模DevOps經驗dev
- 用定租問題學透機器學習的K近鄰演算法機器學習演算法
- 荷蘭官方研究:來自中國的新冠病毒檢測試劑盒優於其他國家
- 荷蘭國際關係研究所:詳解中國的數字絲綢之路(附下載)
- 一位荷蘭程式設計師眼中的DDD - hexmaster程式設計師AST
- 荷蘭阿姆斯特丹大學:研究發現肥胖會改變大腦神經元
- mysql學習整理所有問題MySql
- 學習redis問題記錄Redis
- 【學習】分享幾個學習中的小問題
- 為你的迴歸問題選擇最佳機器學習演算法機器學習演算法
- 荷蘭為什麼應該增加使用可再生能源?
- 2019年12月荷蘭特斯拉Model 3銷量達11563輛
- 2022年比利時、盧森堡和荷蘭電商市場
- 索尼互動娛樂SIE收購荷蘭Nixxes工作室
- 補檔 荷蘭留學概況一站式介紹_趙夢晨的部落格_新東方前途出國