Leetcode位运算题目总结(持续更新)

位运算概念

位运算包括五种:与、或、异或、左移、右移。

异或

  • 两种运算律
  • 0^任何数字=它自己
  • 数字^数字=0

例题

以下例题和剑指:数组中数字出现的次数相同,可一并解决。

1、只出现一次的数字 I

  • 数组中只有一个数字出现一次,其他数字都出现了两次。题解如下:
class Solution {
public:
    int singleNumber(vector<int>& nums) {  //给非空整数数组,返回只出现一次的数字
        int ret=0;
        for(auto x:nums){
            ret ^= x;
        }
        return ret;
    }
};

2、只出现一次的数字 II

  • 数组中有两个数字出现了一次,其他数字都出现了两次,输出这两个出现一次的数字。题解如下:
class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {  
        //想办法把数组拆成两半,每一半都有一个落单的数字,难点在于怎么分成两半。要用左移运算
        int x = 0, y = 0, n = 0, m = 1;  //设置四个起始参数
        for(int num : nums)         // 1. 遍历异或 得到落单的两个数字的异或结果:a^b
            n ^= num;
        while((n & m) == 0)         // 2. 循环左移,计算 m  找到第一个为1的位置   并用m作为分开数组的依据
            m <<= 1;
        for(int num : nums) {       // 3. 再遍历 nums     一边遍历一边异或
            if(num & m) x ^= num;   // 4. 当 num & m != 0   分为一组
            else y ^= num;          // 4. 当 num & m == 0   分为另一组
        }
        return vector<int> {x, y};  // 5. 返回出现一次的数字
    }
};

3、只出现一次的数字 III

  • 数组中有一个数字出现了一次,其他数字出现了三次。求这个落单的数字。
  • 本题除了异或,其他四种位运算都用到了,很综合。题解如下:
    思路
class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int res = 0;
        for (int i = 0; i < 32; i++) { // 每个数字的32位二级制形式
            //遍历每一位,先求和,再%3,最后返回的就是落单的数字
            int sum = 0;
            for (int num : nums) {
                sum += ((num >> i) & 1); 
            }

            if (sum % 3 == 1)     res |= (1 << i);
        }
        return res; 
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值