荷蘭國旗問題

2021-06-18 15:01:37 字數 1300 閱讀 1585

題目是:要求重新排列乙個由字元r,w,b(r代表紅色,w代表白色,b代表藍色,這都是荷蘭國旗的顏色)構成的陣列,使得所有的r都排在最前面,w排在其次,b排在最後。為荷蘭國旗問題設計乙個演算法,其時間複雜度為o(n)

這道題想了相當久。要求時間複雜度是o(n),肯定只能用簡單排序,然後在思想上加以改進。既然只有三種值,那麼很容易就能遇到最大和最小值,這種情況下考慮使用頭尾雙向標記的交換排序。

但是有乙個問題困擾了我很久,怎麼去處理『w』??

一開使我的思路是頭設定i,尾設定j,交換的時候,如果r[i] == 'b' && r[j] == 'r',直接交換並且++i,--j。如果有一方是'w',那麼交換之後指向『w』的座標不動,另一方照常移動。

但是這個時候問題就出來了,如果同時遇到兩個『w』呢?

後來想到一種思路,設定三個座標i, j, k,i和j標誌頭和尾值不正確的位置,即可以用來交換的位置,而k用來標誌正在進行交換的座標。k可以從頭開始 往後遍歷,當遇到j的時候迴圈結束。當k遇到『r』或者『b』的時候,與i或者j交換,如果遇到『w』則繼續往前走。

**如下:

void holandflag(char s, int n) 

++cmp1_count;

while (s[j] == 'b')

if (k < i)

k = i;

++cmp1_count;

while (s[k] == 'w')

if (s[k] == 'r') else

}}

這個演算法時間複雜度會稍大於o(n),因為當遇到一連串『w』的時候,k將會往前走,之後i將會沿著k走過的道路往前走,耗費了無謂的比較時間。

在最好情況下,正序,所比較的次數應該為n+m(其中m是『w』的個數,全都是k比較所耗)。交換次數是0次。

在最差情況下,各個字母都不在自己應該在的位置上,此時無謂的比較將會相當多(即while中的迴圈開始條件比較,但是比較均不成功不會進入迴圈),比較次數將在3n和4n之間。此時交換次數是n-m次(期中m是『w』的個數)

空間複雜度只用到了乙個交換空間,為o(1)。

本以為這解法已經相當完美了,不過。。。

不過晚上回來之後跟舍友商量,舍友說直接用計數排序,遍歷一遍記錄下三種顏色的個數,然後再遍歷一遍依次給陣列賦值。。。時間複雜度最多也就o(2n),空間複雜度o(3)而已。。

尼瑪。。。。瞬間跪了。。不過仔細想了想這種方法似乎還真比我的「標準解法」好,簡單而且完美完成題目的要求,時間效能和空間效能也足夠高。

演算法之路真是無止盡啊。。

荷蘭國旗問題

上方的便是乙個荷蘭國旗,從圖中我們可以很清楚的看出它的特點,它有三個區域組成,即紅,白,藍。好,現在我們的問題出來了。現在我們面前有一張桌子,桌子上整齊的擺放著紅色,白色,藍色三種線條,但他們的順序是凌亂的。我們的要求是 用乙個演算法把這些線條挑出來重新擺放順序,最後的結果就像上圖的荷蘭國旗,紅色在...

荷蘭國旗問題

問題 荷蘭國旗是由紅白藍三種顏色組成,現假設很多這三種顏色的線被打亂放置,要求從頭掃瞄一遍,3種顏色自然分開,顏色順序是紅,白,藍。問題分析 1 編碼 題目中有三種顏色,可以用0 紅,1 白,2 藍進行編碼。3 演算法 a 把n個0,1,2三種元素隨機放入陣列模擬很多這三種顏色的線被打亂放置的場景 ...

荷蘭國旗問題

荷蘭的國旗由紅色 白色和藍色3種顏色組成。現在假設有很多這3種顏色的線被存放在乙個陣列裡,要求每次操作僅能進行一次交換,在原陣列的基礎上操作。待對陣列進行一遍掃瞄後,3種顏色自然分開,顏色順序為紅 白 藍。另外,要求在o n 的複雜度下,是移動次數最少。荷蘭國旗問題 include include ...