Problem Description:
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?
Analysis:
we could use bit manipulation to solve the problem.
00, 01, 10 represent 3 states, which for occurrence of 1, 2, 3 times of the incoming bit .
cur (a,b) | incoming(c) | next (a,b) |
---|---|---|
00 | 0 | 00 |
01 | 0 | 01 |
10 | 0 | 10 |
00 | 1 | 01 |
01 | 1 | 10 |
10 | 1 | 00 |
We could find the equation for a.
consider the case that a = 1.
we can conclude that
a = a &~b & ~c + ~a & b & c.
The same way :
b = ~a & b & ~c + ~a & ~b &c
we need to find the except one as the question don’t mention whether the one appears one or two time. so for ab
01 , 10 ==> 1 time
00 ==> 0 time
we should return a|b;
The above example is using bit. but when we actually do , we receive the number, for int, it’s 32 -bit, but for each bit we will do the same logic. For this operation, we can do it in parallel which is bit operation.
The more details you can see this link
class Solution {
public:
int singleNumber(vector<int>& nums) {
int a = 0, b = 0;
for (auto c : nums)
{
int tmp = (a & ~b & ~c) + (~a & b &c);
b = (~a & b & ~c) + (~a & ~b &c);
a = tmp;
}
return a | b;
}
};
Here is a regular solution:
int singleNumber(int arr[], int n) {
// Initialize result
int result = 0;
int x, sum;
// Iterate through every bit
for (int i = 0; i < 32; i++)
{
// Find sum of set bits at ith position in all
// array elements
sum = 0;
x = (1 << i);
for (int j=0; j< n; j++ )
{
if (arr[j] & x)
sum++;
}
// The bits with sum not multiple of 3, are the
// bits of element with single occurrence.
if (sum % 3)
result |= x;
}
return result;
}