题目
在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。
示例 1:
输入:nums = [3,4,3,3]
输出:4
示例 2:
输入:nums = [9,1,7,9,7,9,7]
输出:1
解题思路
-
查找每一个二进制位上1出现的次数,没出现为00(出现三次则抵消变为00),出现一次为01,出现两次为10。
-
因此用两个二进制位表示这三种状态:a,b(具体到题目中需要有很多的二进制位表示int的每一位,因此直接用两个int变量来表示每一个二进制位上的情况)。
-
具体真值表如下:
-
由上述真值表写出(只需要找出a’和b’中为1的表项,然后进行化简):
a’ = (~a & b & c) | (a & ~b & ~c)
b’ = ~a & (b ^ c) -
因为最终只存在一个数字出现1次,所以结果只需要返回b就行。
代码
class Solution {
public:
int singleNumber(vector<int>& nums) {
//因为一个位上存在三种状态,当出现三次1,为状态00:
//00.该位没有出现过1
//01.该位出现过一次1
//10.该位出现过两次1
int a = 0; //记录状态的高位
int b = 0; //记录状态的低位
int a1, b1; //记录中间结果
for(int c : nums){
a1 = (~a & b & c) | (a & ~b & ~c);
b1 = ~a & (b ^ c);
a = a1;
b = b1;
}
//因为最后的结果是01,即有一个数字只出现一次,所以输出b
return b;
}
};