题目
链接 https://leetcode-cn.com/problems/reverse-bits/submissions/

预备知识
首先uint32_t的来源是typedef unsigned int uint32_t; ,是无符号整型,四个Byte
然后C++里面还有一个数据类型叫bitset,在头文件bitset 中,每个元素仅占一个bit的空间-详细用法
https://www.cnblogs.com/magisk/p/8809922.html
构造函数
bitset<4>bt; //长度32,默认为0
bitset<32>bt("10101"); //长度32,最右边的五位是10101,其它默认为0
bitset<8>bt(12); //长度为8,值为0000 1100
bitset<4>bt("11010101");
cout<<bt<<endl; //输出11010101
cout<<bt[2]<<endl; //输出1
cout<<bt.test(2)<<endl; //test检查下标为2的值,0返回false,1返回true
同时也可以对bt使用操作符
第一次尝试
一看到这个题目很直观的想法,就是先读一边输入,存到bitset里面,然后再反过来赋值给uint32_t
那么取一个数的最后一位bit可以这样写
n&1;
取反一个数的最后一位(0变为1,1变为0)可以这样写
因为这里n是移位出来的,所以最后一位肯定是0,以下三种方法都可以。但是如果是随机一个n要取反的话,只有第一种方式可以
n=n^1; //如果最后一位是0,那么异或后变为1,反之同理
n=n|1; //1100 | 0001 =1101,同样只适用于最后一位是0的情况
n+=1; //只适用于最后一位是0的情况,如果最后一位是1,会造成进位
^是异或符号,这里用了一个性质,假如右边的值是1,那么结果必定是左值的取反,假如右边的值是0,那么结果仍然是左值,1的bit形式就是0000…0001,刚好可以修改最后一位
结合移位操作符,我们就可以实现遍历bit,或者按照bitset给bit赋值两种方法了
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
uint32_t ans=0;
bitset<32>bt;
int i=0;
while(n){
//依次取出最后一位
bt[i++]=n&1;
n>>=1;
}
//依次按照bt中的值给ans赋值,注意移位是31-i,也就是最高位是31而不是32
for(i=0;i<bt.size();i++){
ans=ans^(bt[i]<<(31-i));
}
return ans;
}
};
运行结果

题解
更简洁的解法
直接按位取出最后一位,然后再赋值给ans。注意要先左移一位ans,这样循环最高位会丢掉一开始的0,然后结果就是刚好逆序了
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
uint32_t ans=0;
for(int i=0;i<32;i++){
ans<<=1;
ans+=n&1;
n>>=1;
}
return ans;
}
};
第二种方法
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
uint32_t ret = 0;
for(int i = 31; i >= 0; i--) {
ret = ret | (((n>>(31-i)) & 1) << i);
}
return ret;
}
};
作者:li-ke-sen
链接:https://leetcode-cn.com/problems/reverse-bits/solution/li-yong-wei-cao-zuo-jie-ti-qian-xian-yi-dong-by-li/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
再贴一篇这个作者的公众号文章,讲位运算的https://mp.weixin.qq.com/s/99HVijYmbk1BrGVi1BqrCg

293

被折叠的 条评论
为什么被折叠?



