編程:找出數組中的特殊數-轉自Si-World

假設有一個數組P有3N+1個整數,其中有N個數每個出現3次,還有一個特殊數僅出現過一次,比如{a,a,a,b,b,b,c}。

要求只遍歷一遍數組將這個數找出來,空間複雜度O(1)。

如果是每個數只出現兩次,那麼只需要把所有的數異或起來就可以得到最終的結果了。

那出現三次呢?下面這個程序巧妙地實現了這一點:

int A = 0, B = 0;
for (int I = 0; I < 3 * N + 1; I++)
{
    A ^= P[I] & ~B;
    B ^= P[I] & ~A;
}

這個程序是什麼原理呢?

 

因爲是按位運算,那麼不同位之間的運算是相互獨立的,所以我們可以假設所有的數都只有1比特。循環體每進行一次循環,

如果P[I]的值爲0,那麼A和B的值不會發生變化。如果P[I]的值爲1,那麼(B,A)的值按照下面的順序進行狀態轉移:

那麼如果某一位若經過3K+1次轉移,A爲1;若經過3K次轉移,A爲0,故最終的A爲所求數。

如果是題目改成數組P有3N+1個整數,其中有N個數每個出現3次,還有一個特殊數出現過兩次,比如{a,a,a,b,b,b,c,c}。

則同樣可以解決,其中最終的B即爲所求

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章