剛才在嚴蔚敏的資料結構習題上看到的這個題。看了幾篇部落格。貌似都沒有結合資料結構的意思來解釋。
讓我有種衝動寫篇文章。。就把這當作我的第一篇博文吧。
問題描述:
荷蘭國旗問題 ,設有乙個僅有紅白藍三種顏色的條塊組成的條塊序列。請編寫乙個時間複雜度為o(n)的演算法,使得這些條塊按紅、白、藍的順序排好,即排成荷蘭國旗的圖案。
解析:演算法一:
首先複雜度為o(n)。這很容易讓人想到掃一遍然後放入3個棧中。這樣空間複雜度就為o(3*n)。
其實這種演算法用到了基數排序的思想。先設定判斷條件。把符合條件的放入相應棧中,然後按序取出。
雖然看上去演算法不穩定。由於只有顏色這一種區分,所以取出的順序可以隨便取。
優點:容易想到。實現不複雜,只用設定3個棧,並且標號就行了。
缺點:空間浪費大。而實際上元素移動的次數為2n。比下面說到的方法要多。
演算法二:
有了演算法一,我們能不能縮小空間的使用呢?答案是可以。
因為簡單一看。如果我們把棧設在原始的陣列中的話。是不是就可以節約3n的空間了?
那麼怎樣把棧塞到原始陣列中呢?其實只用多掃瞄一遍原始陣列就可以了。記錄下rflag wflag bflag的次數就可以了!
如此以來。3個flag變數就成了棧的top變數了!
然後開始掃瞄3個變數的位置,如果是對應相同,那麼就自加。如果不是,就找當前位置的顏色放到對應的棧中。
比方說紅色棧頂事藍色。那麼就和對應的bflag所處位置上元素交換。
然後再來判斷棧頂元素。如果是紅色。那麼ok。如果是白色那麼就繼續交換。直到為紅色為止。
如果滿了的話就把wflag換成rflag的位置。那麼就只和bflag交換了。
優點:空間大幅減少。相對演算法一的移動次數相對減少,大概是n樣子(似乎再複雜的情況交換次數也是n,有興趣的可以自己畫畫)。
缺點:實現比較複雜。邏輯也相對前面的複雜一點。
演算法三:
有了演算法二,又沒辦法讓2n次掃瞄變成n次呢?答案也是確定的~~~
假如我們只設定兩個棧。乙個紅,乙個藍。那麼我們遇到藍棧底就放到最右,紅棧底放到最左。
再設定乙個中間變數就ok了~
如何實現呢?
和演算法二類似。紅藍兩個棧頂都不是對應的紅藍。而是其他顏色。
設定中間變數來掃瞄資料。是紅色,就放入紅棧中。是藍色就放入藍棧中。
如果遇到白色就直接跳過吧~因為白色永遠在中間,不可能入棧~
當bflag==中間變數&&中間變數所指向的位址值為白色,那麼程式結束。
優點:簡單。實現方便。空間占用少。
缺點:仔細想想,如果要確定掃瞄次數,似乎也是2n。所以比較上不佔優。
荷蘭國旗問題
上方的便是乙個荷蘭國旗,從圖中我們可以很清楚的看出它的特點,它有三個區域組成,即紅,白,藍。好,現在我們的問題出來了。現在我們面前有一張桌子,桌子上整齊的擺放著紅色,白色,藍色三種線條,但他們的順序是凌亂的。我們的要求是 用乙個演算法把這些線條挑出來重新擺放順序,最後的結果就像上圖的荷蘭國旗,紅色在...
荷蘭國旗問題
問題 荷蘭國旗是由紅白藍三種顏色組成,現假設很多這三種顏色的線被打亂放置,要求從頭掃瞄一遍,3種顏色自然分開,顏色順序是紅,白,藍。問題分析 1 編碼 題目中有三種顏色,可以用0 紅,1 白,2 藍進行編碼。3 演算法 a 把n個0,1,2三種元素隨機放入陣列模擬很多這三種顏色的線被打亂放置的場景 ...
荷蘭國旗問題
荷蘭的國旗由紅色 白色和藍色3種顏色組成。現在假設有很多這3種顏色的線被存放在乙個陣列裡,要求每次操作僅能進行一次交換,在原陣列的基礎上操作。待對陣列進行一遍掃瞄後,3種顏色自然分開,顏色順序為紅 白 藍。另外,要求在o n 的複雜度下,是移動次數最少。荷蘭國旗問題 include include ...