NC156数组中只出现一次的数(位运算)

描述

给定一个长度为n的整型数组arr和一个整数k,已知arr中只有一个数出现一次,其他数出现k次,返回只出现一次的数
例:
输入:[5,4,1,1,5,1,5],3
返回:4
进阶:时间复杂度 O(32n)O(32n),空间复杂度 O(1)O(1)

解题思路

方法一:排序

class Solution {
public:

    int foundOnceNumber(vector<int>& arr, int k) {
        sort(arr.begin(),arr.end());
        for(int i=0;i<arr.size();i++){
            if(arr[i]==arr[i+1]){
                i+=k-1;
            }else return arr[i];
        }
        return arr[arr.size()-1];
    }
};

方法二:位运算

在这里插入图片描述

位操作判断奇偶
if((a&1)==0){
//偶数
}

把数据转换成二进制,每个位相加,对于相同的数据该位肯定会有k组,取余得到多余的部分就是出现一次的数
在这里插入图片描述
例如上面的对应位累加求和后是413的结果,取余掉多余的部分,则得到011,也就是我们所求的数据。
我们需要用一个长度为32(int型二进制表示最多为32位,4字节)的数组bitSum保存每一位的和
具体来讲实现过程是,先初始化为0,然后对于每个数字,遍历它二进制表示的每一位,如果这一位是1,bitSum对应的那一位就加1。

unsigned int a = 8;
a >> 3;
移位前:0000 0000 0000 0000 0000 0000 0000 1000
移位后:0000 0000 0000 0000 0000 0000 0000 0001

class Solution {
public:

        int foundOnceNumber(vector<int>& arr, int k) {
            // 每个二进制位求和,如果某个二进制位不能被k整除,那么只出现一次的那个数字在这个二进制位上为1。
            int binarySum[32]={0};
            for(int i=0;i<32;i++){//求每个二进制位的和
                int sum=0;
                for(int num:arr){
                    sum+=(num>>i & 1);//依次右移num,同1相与,计算每一位上1的个数
                }
                binarySum[i]=sum;
            }
            int res=0;
            for(int i=0;i<32;i++){
                if(binarySum[i]%k!=0){
                    res += (1<<i);      //左移恢复          
                }
            }
            return res;
        
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值