有乙個陣列,各種陣列出現次數的神組合

2021-06-16 09:34:40 字數 1504 閱讀 7787

1. 基本款:有乙個數出現了一次。其餘的數都出現了兩次

異或,結果就是只出現一次的數。

2.  高階款1  有乙個數出現了一次。其餘的數都出現了三次

基本思想: 假設是32位的整數,定義一種新的bit operation 。 每位操作如下: 1^0=1, 0^1=1, 0^0=0, 1^1=2, 2^1=0...每次按位操作,一直到最後。 

每次操作32次。 複雜度32n, 還是o(n)的  (感慨以下,李博好聰明,果然是ms的人)

(可以用乙個長度為32的陣列,每乙個value儲存對應bit的運算結果)

careercup上的解法,太牛了 

for( i=0; i< 10; i++ )

printf("\n unique element = %d \n", ones );

return 0;

思想:one用來儲存只出現一次bit,two用來儲存出現兩次的bit。

twos |= ones & x
由於one只儲存了出現一次的bit,因此此時two保留了出現兩次的bit,並且可能含有出現三次的bit

ones ^= x ;
包含了出現一次和三次的bit資訊,

not_threes = ~(ones & twos) ;

ones &= not_threes ;

twos &= not_threes ;

刪除one two中出現三次的bit資訊。

3. 高階款2有兩個數出現了一次。其餘的數都出現了兩次

參考基本款,如果能夠把原陣列分為兩個子陣列。在每個子陣列中,包含乙個只出現一次的數字,而其他數字都出現兩次。如果能夠這樣拆分原陣列,按照前面的辦法就是分別求出這兩個只出現一次的數字了。

我們還是從頭到尾依次異或陣列中的每乙個數字,那麼最終得到的結果就是兩個只出現一次的數字的異或結果。因為其他數字都出現了兩次,在異或中全部抵消掉了。由於這兩個數字肯定不一樣,那麼這個異或結果肯定不為

0,也就是說在這個結果數字的二進位制表示中至少就有一位為

1。我們在結果數字中找到任乙個為

1的位的位置,記為第

n位。現在我們以第

n位是不是

1為標準把原陣列中的數字分成兩個子陣列,第乙個子陣列中每個數字的第

n位都為

1,而第二個子陣列的每個數字的第

n位都為0。

現在我們已經把原陣列分成了兩個子陣列,每個子陣列都包含乙個只出現一次的數字,而其他數字都出現了兩次。因此到此為止,所有的問題我們都已經解決。

int* twotwice(int * a, int size){

int * result = new int[2];

result[0] = 0;

result[1] = 0;

for(int index=0; index

找出乙個陣列中各個數字出現的次數

看了prime第一章,突發奇想了乙個問題,如何寫乙個演算法去找出乙個陣列中各個數字出現的次數呢?方法一 可以使用我們經常寫的演算法,氣泡排序之類的,首先對陣列進行排序,然後根據prime中第一章的寫法。算出每個數字出現的次數。include include using namespace std i...

找出乙個陣列中出現次數最大的數

描敘 一大堆資料裡面,數字與數字之間用空格隔開,找出出現次數最多的乙個數字的演算法 includevoid findmosttimesdigit int src int srclen if tempcount maxcount else if tempcount maxcount printf 出現...

乙個陣列中有乙個數字的次數超過了陣列的一半

問題描述 乙個陣列中有乙個數字的次數超過了陣列的一半,求出這個字元。如 int a 求出超過一半的數字是2。問題分析 方法1 時間複雜度o n 思路 如果乙個數出現的次數超過陣列一半的長度,那麼就是說出現的次數比其他所有數字出現的次數還要多。因此我們可以考慮儲存2個值,乙個是陣列中的乙個數,乙個是數...