轉自:http://www.acmerblog.com/leetcode-solution-single-number-ii-6317.html
Single Number
Given an array of integers, every element appears twice except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
標籤: Hash Table Bit Manipulation
分析
異或,不僅能處理兩次的情況,只要出現偶數次,都可以清零。
代碼1
01 |
//
LeetCode, Single Number |
02 |
//
時間複雜度O(n),空間複雜度O(1) |
03 |
class Solution
{ |
04 |
public : |
05 |
int singleNumber( int A[], int n)
{ |
06 |
int x
= 0; |
07 |
for ( size_t i
= 0; i < n; ++i) |
08 |
x
^= A[i]; |
09 |
return x; |
10 |
} |
11 |
}; |
代碼2
1 |
//
LeetCode, Single Number |
2 |
//
時間複雜度O(n),空間複雜度O(1) |
3 |
class Solution
{ |
4 |
public : |
5 |
int singleNumber( int A[], int n)
{ |
6 |
return accumulate(A,
A + n, 0, bit_xor< int >()); |
7 |
} |
8 |
}; |
-------------------------------------------------------------------------------------------------
Single Number II
Given an array of integers, every element appears three times except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
標籤: Bit Manipulation
分析
本題和上一題 Single Number,考察的是位運算。只有一個元素只出現了一次
方法1:創建一個長度爲{sizeof(int)}的數組{count[sizeof(int)]},{count[i]}表示在在$i$位出現的1的次數。如果{count[i]}是3的整數倍,則忽略;否則就把該位取出來組成答案。
方法2:用{one}記錄到當前處理的元素爲止,二進制1出現“1次”(mod 3 之後的 1)的有哪些二進制位;用{two}記錄到當前計算的變量爲止,二進制1出現“2次”(mod 3 之後的 2)的有哪些二進制位。當{one}和{two}中的某一位同時爲1時表示該二進制位上1出現了3次,此時需要清零。即\textbf{用二進制模擬三進制運算}。最終{one}記錄的是最終結果。
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ret=0;
int flg[sizeof(int)*8];
fill_n(&flg[0], sizeof(int)*8, 0);//要初始化爲0!!
for(int i=0;i<nums.size();i++)
{
for(int j=0; j<sizeof(int)*8; j++)
{
flg[j] += ( (nums[i]>>j) & 1 );// 累計j位上1的個數
flg[j]%=3;//清零操作
}
}
for(int j=0; j<sizeof(int)*8; j++)
{
ret += (flg[j]<< j) ;//flg中元素要麼是1,要麼是0;nums只有一個元素值出現過一次
}
return ret;
}
};
代碼1
01 |
//
LeetCode, Single Number II |
02 |
//
方法1,時間複雜度O(n),空間複雜度O(1) |
03 |
class Solution
{ |
04 |
public : |
05 |
int singleNumber( int A[], int n)
{ |
06 |
const int W
= sizeof ( int )
* 8; //
一個整數的bit數,即整數字長 |
07 |
int count[W]; //
count[i]表示在在i位出現的1的次數 |
08 |
fill_n(&count[0],
W, 0); |
09 |
for ( int i
= 0; i < n; i++) { |
10 |
for ( int j
= 0; j < W; j++) { |
11 |
count[j]
+= (A[i] >> j) & 1; |
12 |
count[j]
%= 3; |
13 |
} |
14 |
} |
15 |
int result
= 0; |
16 |
for ( int i
= 0; i < W; i++) { |
17 |
result
+= (count[i] << i); |
18 |
} |
19 |
return result; |
20 |
} |
21 |
}; |
代碼2
01 |
//
LeetCode, Single Number II |
02 |
//
方法2,時間複雜度O(n),空間複雜度O(1) |
03 |
class Solution
{ |
04 |
public : |
05 |
int singleNumber( int A[], int n)
{ |
06 |
int one
= 0, two = 0, three = 0; |
07 |
for ( int i
= 0; i < n; ++i) { |
08 |
two
|= (one & A[i]); |
09 |
one
^= A[i]; |
10 |
three
= ~(one & two); |
11 |
one
&= three; |
12 |
two
&= three; |
13 |
} |
14 |
15 |
return one; |
16 |
} |
17 |
}; |