$ones$存的是某一位上的1出现的次数是否是模3余1的
$twos$存的是某一位上的1出现的次数是否是模3余2的
位运算中每一位的运算都是独立的,互不影响,因此可以独立看待每一位。
最终的答案就是$ones$,因为答案只出现一次,因此每一位都是模3余1的
考虑任意一位:
该位已经出现$3k+2$次: ones=0
、twos=1
因为two=1
,所以~twos=0
,代入式子得到ones=0
; twos^x=0
代入式子得到twos=0
。即最终会变成$(0,0)$
该位已经出现$3k+1$次: ones=1
、twos=0
因为one=1
,所以ones^x=0
,代入式子得到ones=0
;twos^x=1
,同时~ones=1
,两者代入式子得到 twos=1
。即最终会变成$(0,1)$
该位已经出现$3k$次: ones=0
、twos=0
因为ones=0
,所以ones^x=1
,同时~twos=1
,两者代入式子得到ones=1
;因为ones=1
,所以~ones=0
,代入式子得到twos=0
。即最终会变成$(1,0)$
可以这样理解,ones能否变为1一方面需要取决于自身原来是否为0,另一方面取决于two是否是0,如果tow是1,说明已经出现过两次,加上现在这个1,这位的1就将出现三次,ones显然不能为0.
two能否变为1一方面取决于自身原来是否为0,另一方面取决于已经已经计算过的ones是否为0,如果ones为0,说明已经原来已经ones为1,只是因为加上一个1变为了0而已,也就意味着有2个1.
class Solution {
public:
int findNumberAppearingOnce(vector<int>& nums) {
int ones = 0, twos = 0;
for (auto x : nums)
{
ones = (ones ^ x) & (~twos);
twos = (twos ^ x) & (~ones);
}
return ones;
}
};