leetcode#数组中只出现一次的数字 (包含按位异或)

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int res=0;
        for(int i=0;i<nums.size();i++){
            res^=nums[i];
        }
        return res;
    }
};

面试问我这个,不能占用空间,没刷题还真不一定知道(面试一定要多刷题再上,跟高考一样的,不能存有侥幸心理,除非,啥题没见过都会的那种大神。。。不得不承认自己是个菜鸡)

异或操作,a^b,如果a和b相等,结果为1,如果a和b不想等,结果为0 ,所以,全员异或,相等元素异或都化为0了,结果就剩下那一个形单影只的了。

 

进阶版:

137. 只出现一次的数字 II

除了一个出现1次,其余均出现3次,利用不重复set,求和*3-2*nums就是两倍的目标。提交代码没过。。应该是溢出了

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        unordered_set<int> res(nums.begin(),nums.end());//不重复set的初始化,可以通过begin-end
        return (3*accumulate(res.begin(),res.end(),0)-accumulate(nums.begin(),nums.end(),0))/2;

    }
};

改成自己写求和函数:

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        unordered_set<int> res(nums.begin(),nums.end());//不重复set的初始化,可以通过begin-end

        return (3*sum(res)-sum_v(nums))/2;

    }
    long sum(unordered_set<int> res){
        long re = 0;
        unordered_set<int>::iterator it= res.begin();
        while(it!=res.end()){
            re+=*it;
            it++;
        }
        return re;
    }
    long sum_v(vector<int> res){
        long re=0;
        for(int num:res){
            re+=num;
        }
        return re;
    }
};

https://leetcode-cn.com/problems/single-number-iii/

有两个出现1次,其余出现2次,先将全部按位异或,得到的是两个数不等的二进制位为1,从右侧到左侧,找到第一个等于1的二进制位下标,这个位可以将两个数分离开,分成两部分,两部分中其余数都是成对的,这样再分别两部分异或就得到解了。

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int res=0;
        for(int num:nums)
            res ^= num;
        int idx=0;
        while(((res>>idx) & 1)==0) idx++;
        int res1=0,res2=0;
        for(int num:nums){
            if((num>>idx) & 1) res1 ^= num;
            else res2 ^= num;
        }
        vector<int> re;
        re.push_back(res1);
        re.push_back(res2);
        return re;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值