标签:例题 运算 nums int xm mask 经典 x2 x1
异或实现加法
int add(int a, int b){
return a & b == 0 ? a ^ b : add(a ^ b, (a & b) << 1);
}
Single Number
问题描述:数组中有一个元素出现了p次,其他元素均出现了k次,求该元素
解决方法:
正常思路是统计每个元素出现的次数,即可求出该元素,通过位运算,我们可以实现对元素的统计
先令p = p % k,这样我们统计的上限最多为k,需要\(m = \log \left \lceil k \right \rceil\)个位来表示,也就是对每个位进行计数。
我们先单单看一位,比如32位整数的第一位1st,对于新来的数,如果新来的数该位为1,则我们需要增加第一位对应的m-counter计数器,当计数器达到k时清空为0,最后的p的二进制表示对应的x即可。
先用一个例子说明一下,如k=5,p=3那么对于32位整数的第一位而言,如果single number的该位为1的话,那么该位对应的计数器必定计数了k * r(r为整数) + p次,由于p=3(二进制11)那么该计数器的第一位和第二位都会被置为1,其他位同理,返回x1或者x2即可
现在的主要问题就为当一个位上的1或0来的时候
- 如何在计数器上实现加法
- 如何在计数器计数达到k时清零
对于第一个问题,我们知道只有当前m-1个数全是1的时候,遇到0才会进位,
xm ^= (xm-1 & xm-2 & .. & i)
xm-1 ^= ( xm-2 & .. & i)
x1 ^= i
对于第二个问题,我们可以用掩码解决,假定k的二进制表示为101,那么只要第3位和第1位为1,说明计数器已满,需要清0
mask = ~ (x1 & ~x2 & x3)
x1 &= mask
xm &= mask
例题
137. Single Number II
k=3, p = 1
class Solution {
public:
int singleNumber(vector<int>& nums) {
int x2 = 0, x1 = 0, mask;
for(int i : nums){
x2 ^= (x1 & i);
x1 ^= i;
mask = ~(x1 & x2);
x1 &= mask;
x2 &= mask;
}
return x1;
}
};
另一种思路也可以使用01来实现三进制,根据真值表写出逻辑表达式
class Solution {
public:
int singleNumber(vector<int>& nums) {
int a = 0, b = 0;
for(int i = 0; i < nums.size(); i++){
int t = (~a&b&nums[i]) | (a&~b&~nums[i]);
b = (~a&b&~nums[i]) | (~a&~b&nums[i]);
a = t;
}
return a | b;
}
};
参考
标签:例题,运算,nums,int,xm,mask,经典,x2,x1 来源: https://www.cnblogs.com/qbits/p/11369631.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。