力扣 190. 颠倒二进制位

题目

链接 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值