[leetcode]single number

题目:

Given an array of integers, every element appears twice except for one. Find that single one.

这题的标签是hash table和bit manipulation,首先想到bit manipulation的思路,由于一个整型数和自己的异或操作得到是全零,全零和任何整型异或都不会改变整型的位表示。所以将数组所有元素取异或操作即可。

class Solution {
public:
    int singleNumber(int A[], int n) {
        if(n<=0){
            return 0;
        }
        int res=0;
        for(int i=0;i<n;++i){
            res^=A[i];
        }
        return res;
    }
};

然后是一个变题:

Given an array of integers, every element appears three times except for one. Find that single one.


注意到,这次重复的元素都出现了三次,所以上面简单的XOR做法就没用了。

对于数组里的所有数,其1~32位的所有‘1’的个数只能是3n或3n+1(n>=0)。对于每一位,我们用一个模为3的计数器,(B1,B0),对于(B1,B0):

(1,1)表示此位上已经出现了3次‘1’

(1,0)表示此位上已经出现了2次‘1’

(0,1)表示此位上已经出现了1次‘1’

(0,0)表示此位上已经出现了0次‘1’

那么对于32位,我们可以用b1,b0两个整型数来分布表示所有32位上的B1和B0,同时我们用变量reset来表示在每一位是否‘1’已经出现了3的整数倍次,如果是则设置reset此位为1,然后将b1,b0对应位重置为0。这样遍历完整个数列,b1必然为全0向量,b0则是那个要找的数。

将b0,b1,reset都初始化为0,b0的更新很显然为b0^=A[i],而B1设置为1只当B0为1且A[i]对应为为1。同时当B0,B1同时为1时要重置。

代码如下:

class Solution {
public:
    int singleNumber(int A[], int n) {
        int b0=0,b1=0,reset=0;
        if(n<=0){
            return 0;
        }
        for(int i=0;i<n;++i){
            b1|=b0&A[i];
            b0=b0^A[i];
            reset=b0&b1;
            b0=b0^reset;
            b1=b1^reset;
        }
        return b0;
    }
};

第二题用到了更加巧妙地位操作方法,如果说不是3个重复,而是4个重复的,5个重复的,我们同样可以用这种方法,用模4计数器或者模5计数器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值