Skip to content

Commit 44c7131

Browse files
committed
Add explaination for "Single Number I/II"
1 parent 8dfaebf commit 44c7131

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

src/singleNumber/singleNumber.II.cpp

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,71 @@
1414

1515
class Solution {
1616
public:
17+
Solution(){
18+
srand(time(0));
19+
}
20+
21+
//random invoker
1722
int singleNumber(int A[], int n) {
23+
if (rand()%2){
24+
return singleNumber_1(A, n);
25+
}
26+
return singleNumber_2(A, n);
27+
}
28+
29+
/*
30+
* This solution is clear & straightforward implementation.
31+
*
32+
* We use an array of 32 length(e.g. count[32]) to count the the bits for all of numbers.
33+
*
34+
* Because the same number appear 3 times, which means the sum of i-th bits for all numbers should be 3 times.
35+
*
36+
* In other word, the sum of i-th bits mod 3, it must be 0 or 1. 1 means that is the single number bit.
37+
*
38+
* This solution can be easy to extend to "every element appears k times except for one."
39+
*
40+
*/
41+
int singleNumber_1(int A[], int n) {
42+
int count[32] = {0};
43+
int result = 0;
44+
for (int i = 0; i < 32; i++) {
45+
for (int j = 0; j < n; j++) {
46+
if ((A[j] >> i) & 1) {
47+
count[i]++;
48+
}
49+
}
50+
result |= ((count[i] % 3) << i);
51+
}
52+
return result;
53+
}
54+
55+
56+
/*
57+
* The following solution is popular solution on Internet, but it looks it's not easy to understand.
58+
*
59+
* Actually, it just optimizes the above soultion.
60+
*
61+
* Let's see how it improve the above.
62+
*
63+
* We use three bitmask,
64+
* 1) `ones` represent the i-th bit had apear once.
65+
* 2) `twos` represent the i-th bit had apear twice.
66+
* 3) `threes` represent the i-th bit had apear three times.
67+
*
68+
* When the i-th bit had appeared for the third time, clear the i-th bit of both `ones` and `twos` to 0.
69+
* The final answer will be the value of `ones`
70+
*
71+
*/
72+
int singleNumber_2(int A[], int n) {
1873
int ones = 0, twos = 0, threes = 0;
1974
for (int i = 0; i < n; i++) {
2075
twos |= ones & A[i];
21-
ones ^= A[i];// 异或3次 和 异或 1次的结果是一样的
22-
//对于ones 和 twos 把出现了3次的位置设置为0 (取反之后1的位置为0)
76+
ones ^= A[i];
2377
threes = ones & twos;
2478
ones &= ~threes;
2579
twos &= ~threes;
2680
}
2781
return ones;
2882
}
83+
2984
};

src/singleNumber/singleNumber.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
**********************************************************************************/
1414

1515
#include <stdio.h>
16-
16+
// This is classical interview question
17+
// As we know, the same number XOR together will be 0,
18+
// So, XOR all of numbers, the result is the number which only appears once.
1719
int singleNumber(int A[], int n) {
1820
int s = 0;
1921
for(int i=0; i<n; i++){

0 commit comments

Comments
 (0)