【位运算题解3】

【位运算题解3】,第1张

LC中等题1

题目描述:461.汉明距离
两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。


给定两个整数 X 和 y , 计算并返回它们之间的汉明距离

(1)1010 ^ 0011 = 1001
(2)相当于两个数进行异或运算 ,结果位1的个数,就是汉明距离

代码详解C++:

class Solution {
public:
    int hammingDistance(int x, int y) {
        int n = (x ^ y);
        int c = 0;       //计数器
        while(n) {
            n &= (n-1);  //进行与运算消去1
            ++c;
        }
        return c;
    }
};

LC中等题2

题目描述:693. 交替位二进制数
给定一个正整数,检查它的二进制表示是否总是 0、1 交替出现:换句话说,就是二进制表示中相邻两位的数字永不相同。


(1)二进制11 = 十进制 3
(2)做法就是n不断右移1位,与11进行与运算,当结果为11或00的时候就说明存在两个相邻位置的数字是相同的。



(3)举例:当 n = 0101101 时,当右移两位后 n = 01011,这时01011 & 11 =3 ,这就检测出了相邻位相同的情况。


class Solution {
public:
    bool hasAlternatingBits(int n) {
        while(n) {
            if ((n & 3) == 3 || (n & 3) == 0) {
                return false;
            }
            n >>= 1;
        }
        return true;
    }
};

LC中等题3

题目描述:1863. 找出所有子集的异或总和再求和
给定一个整型数组,求出数组中每个子集的异或总和,计算并返回这些值相加之和。


思路:
(1) 集合子集数目是 2n 个,判断每个集合二进制1的位置,将该位置的数进行异或。



(2)将每个集合的异或结果进行相加。



举例:

int subsetXORSum(int* nums, int numsSize){
     int i, j, ans;
     int sum = 0;
     for (i = 0; i < (1 << numsSize); i++) {   //0 ~ 2^n -1 枚举每个子集
         ans = 0;
         for(j = 0; j < numsSize; j++){        //判断每个集合二进制数第0位到第n-1位之间1的位置
             if(i & (1<<j)) {
                 ans ^= nums[j];               //如果从低到高第j为1,就说明集合中存在nums[j]
             }
         }
         sum += ans;                           //将每个集合的异或值相加
     }
     return sum;
}

LC中等题4

题目描述:371. 两整数之和
给你两个整数 a 和 b ,不使用 运算符 + 和 - ​​​​​​​,计算并返回两整数之和。


思路:
(1) 两数相加可以看成,带进位的加和加上不带进位的加和。



(2)不断进行递归,直到没有进位时,异或可以看成两数之和时,终止。



举例:
不带进位的加和: a ^ b = 1000 ^ 1010 = 0010
带进位加和的值:(a & b) << 1 = (1000 & 1010) << 1 = 10000

求:a + b = 10010,也就是:

由于需要一直进行加法,所以要不断通过递归进行,递归的终止条件是b=0,也就是没有进位,那么异或就是两数之和。


int getSum(int a, int b){
     return b == 0 ? a : getSum(a ^ b, (unsigned int)(a & b) << 1);
}
! ! ! LC中等题5

题目描述:面试题 05.01. 插入
给定两个整型数字 N 与 M,以及表示比特位置的 i 与 j(i <= j,且从 0 位开始计算)。



编写一种方法,使 M 对应的二进制数字插入 N 对应的二进制数字的第 i ~ j 位区域,不足之处用 0 补齐。


思路:
(1)先将N的 i ~ j 位都归 0,为N’
(2)再将M左移i位 与 N’ 进行 或运算
举例:
N = 1010101111 M = 101
将 N 的 i~j 位归 0,采用与运算,详细见代码吧😎

class Solution {
public:
    int insertBits(int N, int M, int i, int j) {
        int ans;
        for (int k = i; k <= j; k++) {
            N &= ~(1 << k);  //将第K位为0的数与N进行与运算,消去第k位的1
        }
        return N | (M << i);
    }
};

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/567692.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)

保存