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?
Solution 1
I think many coder confused how to generate the code.
This is my analysis, use Truth table to generate code:
Consider every bit in a number, if this bit appear 3 times then set it to zero.
so here is 3 state of one bit, we can use two bit to indicate it.
we use 00 -> 01 -> 10 -> 00...
00: bit 1 appear 0 time.
01: bit 1 appear 1 time.
10: bit 1 appear 2 times.
so every bit 1 appear 3 times, the state will go to 00
but for the single number, every bit 1 in it, its status is 01
we can use two integer to represent the status, named first, second
public static int singleNumber(int[] nums) {
int one = 0;
int two = 0;
for(Integer i : nums){
one = (one ^ i) & ~ two;
two = (two ^ i) & ~ one;
}
return one;
}
Solution 2 General
//General way
//https://leetcode.com/discuss/31595/detailed-explanation-generalization-bitwise-operation-numbers
public int singleNumber2(int[] nums) {
int x1 = 0;
int x2 = 0;
int mask = 0;
for (int i : nums) {
x2 ^= x1 & i;
x1 ^= i;
mask = ~(x1 & x2);
x2 &= mask;
x1 &= mask;
}
return x1; // p = 1, in binary form p = '01', then p1 = 1, so we should return x1;
// if p = 2, in binary form p = '10', then p2 = 1, so we should return x2.
}