颠倒二进制位[LeetCode-190]

题目描述

思路分析

一个数的二进制逆置,其实就是从低位往高位依次遍历每一个二进制位,然后将该二进制位左移一定的值,比如如果是最低位, 则左移31位(二进制位是从0开始,因此最大左移31位,而不是32),如果是最后一位,则左移0位,然后将每一位左移后的值相加即可。

代码实现1

class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        // 7--->111
        // 111000000000...
        uint32_t res = 0;
        int i = 31;
        while(i >= 0) {
            // 得到当前位的值 0 或者 1
            int cur_bit_value = n % 2;
            // 左移一定的位,并加到原数值里
            res += (cur_bit_value << i);
            // 原数右移一位,将次低位变为最低位,继续循环
            n >>= 1;
            i--;
        }
        return res;
    }
};
复制代码

代码实现2(某网友的分治思路)

分而治之的思想,先将高16位与低16位交换,再同时交换每16位中的高低两个8位,然后基本类似地二分做下去,直到最后是每两位之间交换高低两个一位。可见,解法二要比解法一更高效,解法一是 O( sizeof(int) ),解法二是 O( log_2 sizeof(int) )。

class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        n = (n >> 16) | (n << 16);
        n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8);//注意优先级 
        n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4);
        n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2); // 4位的低2位为3,高2位为12(即c)
        n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1); // 相当于&1010  &0101
        return n;
    }
};
复制代码

你可能感兴趣的:(颠倒二进制位[LeetCode-190])