LeetCode Missing Number ,SingleNumber I II III
阿新 • • 發佈:2019-02-13
原文地址:
基本問題
問題描述: 給定一個數組, 其中有一個數出現了p次, 其他數都出現了k次, 找出出現p次的數(其中 p>0 p%k != 0), 求出現p次的數.
基本問題解法
一,32 個計數器
對於一個32 bit 的整數, 我們將每一位都看作是獨立的, 並且設定32個計數器, 每個計數器對應於一位,然後統計所有數的該位上有多少個1。如果結果對k取模後為 0 則說明結果中該位應該取0, 否則該位應該取1。
虛擬碼如下:
count1 = 0;
count2 = 0;
...
count 32 = 0;
foreach(var i in nums)
count1 += ((i& 0x01 ) ? 1 : 0) %k;
count2 += ((i& 0x02) ? 1 : 0) %k;
...
count32 += ((i& 0x80000000) ? 1: 0) %k;
end foreach;
ret = 0;
ret |= (count1 ? 0x01: 0);
ret |= (count2 ? 0x02: 0);
...
ret |= (count32 ? 0x80000000: 0);
return ret;
二, 模擬加法
可以看出第一種方法十分繁瑣,而且佔用空間比較大, 需要32 個整數。其實用32 個計數器是存在冗餘的,因為一般k比較小, 不會佔用整數的大小。解法1 中count 分佈可以看作如下矩陣:
Count1 1,2,3,4,5… 32
Count2 1,2,3,4,5… 32
Count3 1,2,3,4,5… 32
….
Count32 1,2,3,4,5… 32
將矩陣向左旋轉90度,
Count1 Count2 Count3 …. Count32
32 32 32 32
…..
2 2 2 2
1 1 1 1
這樣我們將每行看做一個數。
此時1~log(k) 行是儲存資料的行, 之後的行都可以刪除。
此時需要考慮如何實現加法, 如何進行取模操作。
此時參考英文原文中的方法進行。
需要注意的是:
在k = 2的m次 時, 可以只使用m個數, 並且取模操作可以省略, 因為進位會被忽略。