LeetCode——颠倒二进制位&位1的个数

NO.190 颠倒二进制位 简单 、NO.191 位1的个数 简单

NO.190 颠倒二进制位 简单

YLqIJA.png

思路一:逐位颠倒 每次用 & 运算取出 n 的最低位,将 ans 左移一位后用 ^ 运算保存得到的最低位。每次将 n 右移一位。

public int reverseBits(int n) {
    int ans = 0;
    for (int i = 0; i < 32; i++) {
        ans = (ans << 1) + (n & 1);
        n >>= 1;
    }
    return ans;
}

思路二:分治算法 折半交换,直接看个例子:

n = 11010001
第一步: n&11110000>>>4 | n&00001111<<4 = 00011101
第二步: n&11001100>>>2 | n&00110011<<2 = 01000111
第三步: n&10101010>>>1 | n&01010101<<1 = 10001011
得到结果: 10001011

32 位整数翻转也是一样的道理,先翻转前 16 位和后 16 位,再翻转 0~7 位和 8~15 位、16~23 位和 24~31 位,接着是 4 位一翻转、2 位一翻转、最后 1 位一翻转。

public int reverseBits(int n) {
    n = ((n & 0xffff0000) >>> 16) | ((n & 0x0000ffff) << 16);
    n = ((n & 0xff00ff00) >>> 8) | ((n & 0x00ff00ff) << 8);
    n = ((n & 0xf0f0f0f0) >>> 4) | ((n & 0x0f0f0f0f) << 4);
    n = ((n & 0xcccccccc) >>> 2) | ((n & 0x33333333) << 2);
    n = ((n & 0xaaaaaaaa) >>> 1) | ((n & 0x55555555) << 1);
    return n;
}

NO.191 位1的个数 简单

YLq5id.png

思路一:逐位统计 用 & 运算得到最后一位是 1 还是 0,每次统计完将 n 用 >>> 无符号右移 1 位。

public int hammingWeight(int n) {
    int count = 0;
    for (int i = 0; i < 32; i++) {
        count += n & 1;
        n >>>= 1;
    }
    return count;
}

思路二:减 1 统计 看例子:

n = 11010001
n = (n - 1)&n = 11010000 & 11010001 = 11010000
n = (n - 1)&n = 11001110 & 11010000 = 11000000
n = (n - 1)&n = 10111111 & 11000000 = 10000000
n = (n - 1)&n = 01111111 & 10000000 = 00000000 = 0
共计算了 4 次,得到结果:有 4 个 1 。

实现这个方式,每次计算之后计数器 +1 ,直至 n 变为 0,则统计完成。

public int hammingWeight(int n) {
    int count = 0;
    while (n != 0) {
        count++;
        n &= (n - 1);
    }
    return count;
}

本人菜鸟,有错误请告知,感激不尽!

更多题解和源码:github

猜你喜欢

转载自blog.csdn.net/qq_42758551/article/details/106286234