位运算

常见的位运算有:

                 &(有0则为0):001 & 101 = 001

                  |(有1则为1): 001 | 101 = 101

                  ^(异或,相异则为1):001 ^ 101 = 100

                  ~(取反):~111 = 000

                 >>(右移):1101 >> 1 = 110

                 <<(左移) 1101 << 1 = 11010

 

题目1:判断一个数是否为2的幂次方

//解法一:
//1进行左移得到了int类型的最大值,再mod n如果得到0,则n仅有因子2

class Solution{
public:
    bool isPowerOftwo(int n){
        return n > 0 && (1<<30) % n == 0;
    }
}
//解法二:
//n & -n表示的是从低位起到高位的第一个1;
//2的整次幂二进制表示中仅有一个1

class Solution{
public:
    bool isPowerOftwo(int n){
        return n > 0 && (n & -n) == n;
    }
}

题目2:给定一个区间 [L,R] ,判断在这区间内的一个数,若二进制表示中1的个数为质数,输出共有几个这样的数。例:21->10101,1的个数为3,则21满足条件。

class Solution{
public:
    int countPrimeSetBits(int L,int R){
        unodered_set<int> primes({2,3,5,7,11,13,17,19});//先列出20以内的所有素数(例子)
        int res = 0;
        for(int i = 0;i <= R;i++){
            int s = 0;
            for(int k = i;k;k>>=1) s += k & 1;//得到该数二进制中总共几个1,每次&完对k进行加1
            if(primes.count(s))
                res++;
        }
        return res;
    }
}

题目3:给定一个数组,仅有一个数出现次数是奇数,其余均为偶数次,将奇数次的数找出来。(不能使用额外的空间--->可以使用O(1)的空间)

/*
a ^ a = 0
0 ^ a = a
任何数异或自身都为0,而0异或任何数结果为任何数本身。

*/

class Solution{
public:
    int singleNumber(vector<int> &nums){
        int res = 0;
        for(auto x : nums) res ^= x;//异或具备交换律,间隔碰到相同的变为0
        return res;
    }    
}

题目4:给定一定整数,求出该整数的反码。

class Solution{
public:
    int findComplement(int num){
        int res = 0,t = 0;
        while(num){
            res += !(num & 1) << t;
            num >> =1,t++;
        }
        return res;
    }
}

题目5:给定一个数组,仅有两个数出现了1次,其他数出现了2次,找出出现1次的数。(仅使用O(1)的空间)

class Solution{
public:
    vector<int> singleNumber(vector<int> &nums){
        int s = 0;
        for(auto x : nums) s ^= x;

        int k = 0;
        while(!(s >> k & 1)) k++;

        int s2 = 0;
        for(auto x : nums){
            if(x >> k & 1)
                s2 ^= x;

        return vector<int>({s2,s ^ s2});
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值