题目要求时间复杂度是O(n),空间复杂度是O(1)。
异或可以将两个只出现一次的数筛选出来,之后再把这两个数分到两组中,并且将相同的数分到同一组,两组分别异或就能求出两个数。
异或规则是不相同为1,相同为0
所以利用a^b 的结果中为1的某一位作为判断依据
class Solution {
public:vector<int> singleNumbers(vector<int>& nums) {int res=0,a=0,b=0;for(int i:nums){res^=i;}int div=1;//判断依据while((div&res)==0){div=div<<1;}for(int i:nums){//因为a,b不同 所以和div与运算会有不同结果if(div&i){// cout<<"aaaa "<<i<<endl;a^=i;}else{// cout<<"bbbb "<<i<<endl;b^=i;}}return vector<int>{a,b};}
};
剑指 Offer 56 - II. 数组中数字出现的次数 II
将所有数的每一位出现的次数相加 最终结果为3的倍数或者3的倍数余1
所以我们找出3的倍数余1的所有位就是出现一次的数
因为有些数出现三次 所以我们把三次用三种状态表示出来 分别为 00 01 10
出现次数相加 最后状态为 00或01 ‘也就是说我们要找出01状态的所有位
我们用one和two来表示 初始化one和two为0 表示00状态
比如说 n=3
n | 0 | 0 | 1 | 1 |
two | 0 | 0 | 0 | 0 |
one | 0 | 0 | 1 | 1 |
为什么最后返回one
因为最终状态为01 two这一位为0 所以只要返回one就行了
class Solution {
public:int singleNumber(vector<int>& nums) {int one=0,two=0;for(int i:nums){one=one^i&~two;two=two^i&~one;}return one;}
};