1. 程式人生 > >LeetCode Missing Number ,SingleNumber I II III

LeetCode Missing Number ,SingleNumber I II III

原文地址:

基本問題

問題描述: 給定一個數組, 其中有一個數出現了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個數, 並且取模操作可以省略, 因為進位會被忽略。