[leetcode] 136 &137 Single Number Ⅰ Ⅱ

136;

题意很简单,给你一个数组(int),只有一个数字是出现一次的,其余出现两次,不允许使用额外空间,时间复杂度线性。

如果允许使用额外空间的话,可以使用map记录次数,最后遍历,也是O(n)的复杂度;但是现在需要把额外空间也去掉,我们只能向位操作方面想了。

利用异或的特点,可以发现 

(1) a^a =0

(2) 0^ b=b

所以,相同的两个数异或结果肯定是0,而0与唯一的出现一次的数的异或结果是这个数;即对数组进行异或操作,结果就是答案。

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

是上一题的加强版,给你一个数组(int),只有一个数字是出现一次的,其余出现三次,不允许使用额外空间,时间复杂度线性。
(先来一个比较通用的,可以求其余出现n次(只需要取余n)的程序,但是用了很小的额外空间)

异或的思路肯定是不行了,但是我们可以继续考虑位运算,如果一个数出现了3次,那么他的对应的二进制位上1的次数一定是3的整数倍,一旦取余之后不是0,那么肯定是出现一次的那个数。

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int bitsum[32];
        memset(bitsum,0,sizeof(bitsum));
        for(int i=0;i<nums.size();i++)
        for(int j=0;j<32;j++)
        bitsum[j]+=(nums[i]>>j)&1;
        int res;
        for(int i=0;i<32;i++)
        res|=(bitsum[i]%3)<<i;
        return res;
    }
};



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值