【Leetcode】[190] 颠倒二进制位

Author: Xin Pan

Date: 2022.3.13


题目

原题链接

颠倒给定的 32 位无符号整数的二进制位。

解法

考虑使用位运算来做,因为这32位0 1都很明显了。

示例 1:

输入:n = 00000010100101000001111010011100
输出:964176192 (00111001011110000010100101000000)
解释:输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596,
因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。

答案1 位移动+分治

怎么样,看到这个解法惊不惊喜意不意外。说真的,根本没想到分治。看了题解发现用了分治之后效果还是挺明显的。官方分治的题解是如下。

执行用时: 0 ms 内存消耗: 5.7 MB

class Solution{private:const uint32_t M1 = 0x55555555; // 01010101010101010101010101010101const uint32_t M2 = 0x33333333; // 00110011001100110011001100110011const uint32_t M4 = 0x0f0f0f0f; // 00001111000011110000111100001111const uint32_t M8 = 0x00ff00ff; // 00000000111111110000000011111111public:uint32_t reverseBits(uint32_t n){n = n >> 1 & M1 | (n & M1) << 1; // 奇偶交换n = n >> 2 & M2 | (n & M2) << 2; // 每2位交换n = n >> 4 & M4 | (n & M4) << 4; // 每4位交换n = n >> 8 & M8 | (n & M8) << 8; // 每8位交换return n >> 16 | n << 16;}};

我用代码解释下其中的每行的含义。因为位的运算比较抽象,但是效率高。

#include <iostream>
#include <bitset>
using namespace std;int main()
{uint32_t M1 = 0x55555555;uint32_t n = 43261596;// 运算符优先级 << >> 高于 按位与(&) 高于 按位异或(^) 高于 按位或(|)// 我自己记不住 按位与(&) 按位异或(^)  按位或(|) 三个运算什么时候结果是0,什么时候结果是1。为此我变了一个顺口溜// &:全1才是1;// |: 有1就是1;// ^: 不同才是1。// 记住顺口溜我们看下边的代码cout << "输入的二进制表示\t\t" << bitset<sizeof(n) * 8>(n) << endl;//int占4字节,一个字节8位,最终输出的是32个0或1cout << "输入>>1\t\t\t\t" << bitset<sizeof(n) * 8>(n >> 1) << endl;//int占4字节,一个字节8位,最终输出的是32个0或1cout << "M1(奇偶掩膜)\t\t\t" << bitset<sizeof(M1) * 8>(M1) << endl;cout << "输入>>1&M1\t\t\t" << bitset<sizeof(n) * 8>(n >> 1 & M1) << endl;cout << "输入&M1再<<1\t\t\t" << bitset<sizeof(n) * 8>((n & M1) << 1) << endl;cout << "输入>>1&M1 | 输入&M1再<<1\t" << bitset<sizeof(n) * 8>(n >> 1 & M1 | (n&M1) << 1) << endl << endl;cout << "输入的二进制表示\t\t" << bitset<sizeof(n) * 8>(n << 1) << endl;cout << "M1(奇偶掩膜)\t\t\t" << bitset<sizeof(M1) * 8>(M1) << endl;cout << "输入&M1\t\t\t\t" << bitset<sizeof(n) * 8>(n & M1) << endl;cout << "输入&M1<<1\t\t\t" << bitset<sizeof(n) * 8>((n & M1) << 1) << endl;cout << "输入<<1再&M1\t\t\t" << bitset<sizeof(n) * 8>(n << 1 & M1) << endl;system("pause");return 0;
}

结果如下:

  1. &M1这个掩膜相当于固定提取当前奇数位置的值;

那么对于上半部分来说。首先将偶数位置移动到奇数位置,在和M1取按位与计算,就是将输入的偶数信息拿过来了。为什么右移一位不能说是奇数位到偶数位。因为第一位和最后一位会在移动(左移或者右移)过程中直接被抹掉。所以原值等于变了。故而我们不说奇数变到了偶数位置。

那么怎么将原先奇数位置转移到偶数位置呢,就是直接做按位与M1,再左移就可以了。现在我们有了各自移动好位置的奇数和偶数部分,下边就是将它们合并起来,那怎么做?直接做按位或就可以了。

这就完成了奇偶位数的互换工作了。因为采用分支算法,也就是将32位对半分,直到最小的维度相邻的两个值。

反过来我们计算了相邻(奇偶的互换),同理计算每2 4 8 16互换就完成任务了。

答案2 位移动

直接解法,一位位移动

执行用时: 4 ms 内存消耗: 5.9 MB

 class Solution{public:uint32_t reverseBits(uint32_t n){uint32_t nret = 0;for (int i = 0; n > 0, i < 32; i++){nret |= (n & 1) << (31 - i);n >>= 1;}return nret;}};

【Leetcode】[190] 颠倒二进制位相关推荐

  1. leetcode#190 颠倒二进制位

    leetcode#190 颠倒二进制位 题目: 颠倒给定的 32 位无符号整数的二进制位. 示例: 输入: 00000010100101000001111010011100 输出: 001110010 ...

  2. java二进制反转_Java实现 LeetCode 190 颠倒二进制位

    190. 颠倒二进制位 颠倒给定的 32 位无符号整数的二进制位. 示例 1: 输入: 00000010100101000001111010011100 输出: 0011100101111000001 ...

  3. leetcode 190. 颠倒二进制位(位运算)

    颠倒给定的 32 位无符号整数的二进制位. 提示: 请注意,在某些语言(如 Java)中,没有无符号整数类型.在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有 ...

  4. leetcode 190. 颠倒二进制位

    颠倒给定的 32 位无符号整数的二进制位. 示例 1: 输入: 00000010100101000001111010011100 输出: 0011100101111000001010010100000 ...

  5. Leetcode 190. 颠倒二进制位 解题思路及C++实现

    解题思路: 使用移位运算和与运算,将32位二进制数n中的每一位取出来,然后将取出的0或1相应地进行右移操作,最终加和得到结果. 下面的程序中,循环执行32次,每一次循环,得到n的第 i 位数,即 通过 ...

  6. [leetcode]190. 颠倒二进制位

    class Solution {public:uint32_t reverseBits(uint32_t n) {bitset<32>temp(n); //左边是低位,temp[0]是二进 ...

  7. leetcode 190. Reverse Bits | 190. 颠倒二进制位(移位操作,十进制二进制相互转换,打表法)

    题目 https://leetcode-cn.com/problems/reverse-bits/ 题解 方法1:JDK 自带的 Integer.reverse() 方法源码 /*** Returns ...

  8. 【LeetCode】190. 颠倒二进制位 easy / bitset / stoul

    简单题现在目标25分钟吧:中等题一个小时吧. 重点:input: 无符号整型,output: 无符号整型. 颠倒:是指首位颠倒,而不是01颠倒 stoul(str, nullptr, 2) 第三个参数 ...

  9. 文巾解题 190. 颠倒二进制位

    1 题目描述 2 解题思路 2.1 方法1 字符串倒转 class Solution:def reverseBits(self, n: int) -> int:x=bin(n)[2:] #将整数 ...

最新文章

  1. 如何使用ASINetWorkQueue下载实现
  2. QDoc状态status
  3. js事件冒泡与捕捉解析
  4. 《Java程序员面试宝典》读书笔记1
  5. 数据结构--线性表链式存储(链表)--单链表
  6. 7.组件连线(贝塞尔曲线)--从零起步实现基于Html5的WEB设计器Jquery插件(含源码)...
  7. 华为lab-rs-v1-2.9_OSPF区域34
  8. Android P(2)---计划概览
  9. wireless-tools源码分析-iwlist
  10. 智慧酒店系统开发给现代酒店运营注入创新活力
  11. ae去闪插件deflicker使用_夜晚视频灯光去闪烁 Deflicker插件
  12. SSL1284压岁钱
  13. java getvalueat_Java swing jdbc:设置背景颜色,获取素材方法,表格,图片等的切换【诗书画唱】...
  14. 八、管道弯头中流体混合流动与传热
  15. reached end of file while parsing
  16. VTK图像处理之访问图像像素值
  17. 计算机配置8c16g,腾讯云服务器价格表(1核2G/2核4G/4核8G/8核16G配置)
  18. jeecg-boot自动生成代码_PSIM 仿真:如何使用 PSIM12 自动生成代码
  19. 去除nginx.conf文件中注释和空格行方法
  20. kuberbetes 容器探测(liveness/readiness probes)

热门文章

  1. 全球2023年最强和最弱护照排名公布,日本193分排在第一 | 美通社头条
  2. 彻底解决The last packet successfully received from the server was * milliseconds ago问题
  3. iso shell vg220齿轮油_CLP220齿轮油性能
  4. 大数据真实案例:Spark在美团的实践
  5. 日语基础复习 Day 16
  6. 计算机毕业设计Java计算机培训管理(源码+系统+mysql数据库+lw文档)
  7. 综合案例 跳转到主页面
  8. 软件破解简单示例演示
  9. 虚拟化与网络存储技术:虚拟化技术、Qemu-KVM
  10. Ubuntu 修复弹出U盘“An operation is pending”