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?
题意:除了一个元素外,其它元素都是出现三次,求那个元素?
如果是除了一个元素,其它的都出现两次,则所有的数异或就是结果。方法一:统计每位二进制出现次数,若某位二进制出现次数不是3的倍数,则此位为1
<span style="font-size:18px;">class Solution {
public:
int singleNumber(int A[], int n) {
int number[32];
memset(number, 0, sizeof(number));
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < 32; ++j)
{
if (A[i] & (1 << j))
{
number[j]++;
}
}
}
int result = 0;
for (int i = 0; i < 32; ++i)
{
if (number[i] % 3 != 0)
{
result += (1 << i);
}
}
return result;
}
};</span>
方法二:用两个数分别代表对应位1出现的次数对三取模为1、2。
<span style="font-size:18px;">class Solution {
public:
int singleNumber(int A[], int n) {
//总的来说,就是统计各个二进制位1出现的次数。
//可以用one,two的每个二进制位分别代表对应位1出现的次数对三取模为1、2。
//另外one,two的某个二进制位都为0时,则表示那位1出现的次数取模正好为0。
int one = 0, two = 0; //刚开始在每位上1都没出现,所以都是0。
int three = 0; //当one,two的某个二进制位都为1时,表明已经出现了三次,可以取模。
for (int i = 0; i < n; ++i)
{
two |= one&A[i];
one ^= A[i];
three = one&two;
//当出现三次后,one,two清0,相当于取模
one &= ~three;
two &= ~three;
}
return one|two; //因为不知道那个数是出现一次还是两次,所以将出现一次或两次的都返回
}
};</span>