Single Number II
- 題目描寫敘述
- 鏈接地址
- 解法
- 算法解釋
題目描寫敘述
Given 3*n + 1 numbers, every numbers occurs triple times except one, find it.
Example
Given [1,1,2,3,3,3,2,2,4,1] return 4
Challenge
One-pass, constant extra space.
鏈接地址
http://www.lintcode.com/en/problem/single-number-ii/
解法
int singleNumberII(vector <int> A) {
// write your code here
int num[64] = {0};
int ret = 0;
for (int index = 0; index < 64; index++) {
for (int i = 0; i < A.size(); i++) {
num[index] += (A[i] >> index) & 0X01;
}
ret |= ((num[index] % 3 ) << index);
}
return ret;
}
算法解釋
在single Number1我們了解到抑或運算符能夠將兩個同樣的數抵消,如今面對的三個數的,我們在想有什麽方法能夠使同樣的三個數抵消。
相似於異或運算,我們採用不進位的3進制加法,抑或運算是不進位的2進制加法。解法流程例如以下:
1、將每一個數轉換成3進制
2、實行3進制的不進位加法
3、最後剩下的和轉為10進制就是答案
題目要求one-pass。假設按上面的思路來的話,要走兩遍,就不可能是one-pass。所以用把進制轉化和4進制加法綜合在一起做處理。int 數據共同擁有64位。能夠用64變量存儲 這 N 個元素中各個二進制位上 1 出現的次數,最後 在進行 模三 操作,假設為1,那說明這一位是要找元素二進制表示中為 1 的那一位。
復雜度為 O(64*N)
上述算法能夠應對不論什麽同樣位數的解法
如對於single Number ,正確解法為:
int singleNumber(vector &A) {
// write your code here
int num[64] = {0};
int ret = 0;
for (int index = 0; index < 64; index++) {
for (int i = 0; i < A.size(); i++) {
num[index] += (A[i] >> index) & 0X01;
}
ret |= ((num[index] % 2) << index);
}
return ret;
}
Single Number II