剑指Offer 位运算小合集

剑指 Offer 65. 不用加减乘除做加法

在这里插入图片描述

菜鸡思路:

比如5 + 6相当于拆成二进制来运算:

	1 0 1
  + 1 1 0

一个1一个0不进位,两个1进位。

菜鸡代码:

class Solution {
    
    
public:
    int add(int a, int b) {
    
    
        while (b) {
    
    
            int carry = a & b; // 计算 进位的地方
            a = a ^ b; // 计算 本位
            b = (unsigned)carry << 1;//前移进位
        }
        return a;
    }
};

剑指 Offer 15. 二进制中1的个数

在这里插入图片描述

菜鸡思路:

对每一位按位与,不为零,就是1。

菜鸡代码:

class Solution {
    
    
public:
    int hammingWeight(uint32_t n) {
    
    
        int ret = 0;
        for (int i = 0; i < 32; i++) {
    
    
            if (n & (1 << i)) {
    
    
                ret++;
            }
        }
        return ret;
    }
};

剑指 Offer 56 - I. 数组中数字出现的次数

在这里插入图片描述

思路:

感觉位运算都像智力题似的,直接看题解吧:
先对所有数字进行一次异或,得到两个出现一次的数字的异或值。
在异或结果中找到任意为 1的位。
根据这一位对所有的数字进行分组。
在每个组内进行异或操作,得到两个数字。

代码:

class Solution {
    
    
public:
    vector<int> singleNumbers(vector<int>& nums) {
    
    
        int ret = 0;
        for (int n : nums) {
    
    
            ret ^= n;
        }
        //ret最终答案就是那两个只出现一次的的数异或的结果
        int div = 1;
        //找到ret二进制数中第一个1
        while ((div & ret) == 0) {
    
    
            div <<= 1;
        }
        int a = 0, b = 0;
        for (int n : nums) {
    
    
            if (div & n) {
    
    //第一组
                a ^= n;
            } else {
    
    //第二组
                b ^= n;
            }
        }
        return vector<int>{
    
    a, b};
    }
};

剑指 Offer 56 - II. 数组中数字出现的次数 II

在这里插入图片描述

思路:

乍一看非常困难,但是看了别人的思路就能想通

代码:

class Solution {
    
    
public:
    int singleNumber(vector<int>& nums) {
    
    
        int bits[32] = {
    
    0};
        for (int i = 0; i < nums.size(); i++) {
    
    
            int j = 0;
            //得到各个二进制位为1的有多少个
            while (nums[i]) {
    
    
                bits[j] += nums[i] % 2;
                nums[i] /= 2;
                j++;
            }
        }
        int ans = 0;
        for (int i = 0; i < 32; i++) {
    
    
            //利用%3 来求得对应位置上有没有1 有的话乘对应的 2 的i次方
            ans += (1 << i) * (bits[i] % 3);
        }
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_52192405/article/details/124691869