五月集训(第10天)— 位运算

位运算

1. 191. 位1的个数

    思路:
        利用位运算统计1的个数

int hammingWeight(uint32_t n) {
    int ans = 0;
    while (n) {
        ans += (n&1);
        n >>= 1;
    }
    return ans;
}

2. 461. 汉明距离

    思路:
        直接位移统计汉明距离,要注意是最大的一个数为0时才停止比较,否则统计不全。

int hammingDistance(int x, int y){
    int cnt = 0;
    while (x || y) {
        if ((x&1) != (y&1)) cnt++;
        x >>= 1;
        y >>= 1;
    }
    return cnt;
}

    思路:
        利用异或性质统计

int hammingDistance(int x, int y){
    int cnt = 0;
    while (x || y) {
        cnt += ( (x&1) ^ (y&1) );
        x >>= 1;
        y >>= 1;
    }
    return cnt;
}

3. 136. 只出现一次的数字

    思路:
        利用异或性质,出现两次的数异或之后为0,所有数异或后就剩出现奇数次的数的异或值,此题中为只出现一次的数字。

int singleNumber(int* nums, int numsSize){
    int ans = 0;
    for (int i = 0; i < numsSize; i++) ans ^= nums[i];
    return ans;
}

4. 137. 只出现一次的数字 II

    思路:
        利用两位二进制数a[i]b[i]记录第i位出现次数。00 -> 01 -> 10 -> 00
        b = (b ^ nums[i]) & ~a;
        a = (a ^ nums[i]) & ~b;

        示例:[2,2,3,2]
        a = 0 b = 0 num = 2b = (00B ^ 10B) & 11B = 10B; a = (00B ^ 10B) & 01B = 00B
        a = 0 b = 2 num = 2b = (10B ^ 10B) & 11B = 00B; a = (00B ^ 10B) & 11B = 10B
        a = 2 b = 0 num = 3b = (00B ^ 11B) & 01B = 01B; a = (10B ^ 11B) & 10B = 00B
        a = 0 b = 1 num = 2b = (10B ^ 10B) & 11B = 00B; a = (00B ^ 10B) & 11B = 00B
        整个操作过程就是在找是否有1出现:
           step1: 发现a=0 b=0没有1,将b先置为1,然后a发现b=1,有1了,将a置为0
           step2: a=0 b=1有1了,将b先置为0,然后a发现b=0,没有1了,将a置为0
           step3: 发现a=1 b=0有1了,将b先置为0,然后a发现a=1,有1了,将a置为0


int singleNumber(int* nums, int numsSize){
    int a = 0, b = 0;
    for (int i = 0; i < numsSize; i++) {
        b = (b ^ nums[i]) & ~a;
        a = (a ^ nums[i]) & ~b;
    }
    return b;
}
posted @ 2022-05-11 07:17  番茄元  阅读(10)  评论(0)    收藏  举报