LeetCode-Go 位运算实战:190 题 Reverse Bits(颠倒二进制位)的 Go 解法与测试验证
LeetCode-Go 位运算实战190 题 Reverse Bits颠倒二进制位的 Go 解法与测试验证【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go本篇基于 LeetCode-Go 仓库中 190. Reverse Bits 题解文档 展开在完整继承原题描述、示例与解题思路的基础上结合仓库中 8 行核心源码 与 配套测试用例逐行拆解“移位 掩码”的位反转实现。读完后你能掌握 Go 中uint32位运算的标准写法、如何验证 32 位全反转的正确性以及该仓库如何用测试与覆盖率脚本保证题解可复现。题目与需求颠倒 32 位无符号整数的二进制位仓库文档中对题面的原始描述是颠倒给定的 32 位无符号整数的二进制位Reverse bits of a given 32 bits unsigned integer。两个官方示例如下示例 1输入: 00000010100101000001111010011100 输出: 00111001011110000010100101000000 解释: 输入二进制串 00000010100101000001111010011100 表示无符号整数 43261596 返回 964176192其二进制表示为 00111001011110000010100101000000。示例 2输入: 11111111111111111111111111111101 输出: 10111111111111111111111111111111 解释: 输入二进制串表示无符号整数 4294967293返回 3221225471 即 10111111111111111111111111111111。文档同时给出了一条重要的语言相关说明在某些语言如 Java中没有无符号整数类型输入和输出会以有符号整数给出但这不应影响实现——无论整数是有符号还是无符号其内部的二进制表示形式都是相同的。以 Java 为例编译器使用补码twos complement表示有符号整数因此示例 2 的输入4294967293作为有符号整数是-3输出3221225471作为有符号整数是-1073741825。这一点在后面“Go 视角”一节会再展开。核心思路循环 32 次“取最低位、追加到 res”原解题思路文档只给了两句关键描述但已经点破了全部要点简单题要求反转 32 位的二进制位把num不断右移消灭右边最低位的 1将这个 1 给resres不断左移即可实现反转。把这个思路展开每一步做三件事提取num的当前最低位num 1结果只可能是 0 或 1把res整体左移一位res 1为最低位腾出空位把刚提取的位放入res的最低位(res 1) | (num 1)同步右移numnum 1让下一轮的“最低位”变成原来的次低位。循环恰好 32 次后num原本的最低位已经移动到res的最高位num的最高位落在res的最低位——位序完全颠倒。用示例 1 走一遍num 4326159600000010100101000001111010011100第 1 次循环取出最低位0追加给res第 2 次取出次低位0……直到第 32 次把最高位区的1全部搬到res低位最终得到96417619200111001011110000010100101000000。仓库中的 Go 实现仅 8 行的完整源码仓库中该题的解法位于 190. Reverse Bits.go全文如下含 package 声明共 10 行package leetcode func reverseBits(num uint32) uint32 { var res uint32 for i : 0; i 32; i { res res1 | num1 num 1 } return res }逐行分析num uint32是刻意为之。Go 原生提供 8 种整数类型uint8uint64uint32就是“32 位无符号整数”本身类型系统直接对应题目语义无需像 Java 那样用int模拟无符号var res uint32Go 中声明的uint32零值即为0无需初始化for i : 0; i 32; i固定 32 次与输入数值大小无关——这也保证了边界值如0或0xFFFFFFFF同样处理 32 位不会因前导 0 提前结束res res1 | num1一行完成“左移腾位 按位或追加”两个动作。注意|与的 Go 运算符优先级高于|所以该表达式等价于res res1 | (num1)源码中省略括号是安全的num 1对无符号类型执行的是逻辑右移高位补 0不会像 Java 的对int做符号扩展这正是“无论有符号无符号实现不受影响”在 Go 中的自然体现。整个函数没有任何分支与额外内存分配时间上执行常数 32 次迭代O(1) 时间复杂度空间上只有两个寄存器级的 32 位变量O(1) 空间复杂度。测试验证用仓库的两组用例复现题目示例同目录下的 190. Reverse Bits_test.go 采用仓库统一的题解测试模式定义question190结构体把“参数”与“期望答案”成对组织直接对应题目中的两个示例func Test_Problem190(t *testing.T) { qs : []question190{ { para190{43261596}, ans190{964176192}, }, { para190{4294967293}, ans190{3221225471}, }, } fmt.Printf(------------------------Leetcode Problem 190------------------------\n) for _, q : range qs { _, p : q.ans190, q.para190 input : strconv.FormatUint(uint64(p.one), 2) // 32位无符号整数转换为二进制字符串 input fmt.Sprintf(%0*v, 32, input) // 格式化输出32位,保留前置0 output : reverseBits(p.one) outputBin : strconv.FormatUint(uint64(output), 2) outputBin fmt.Sprintf(%0*v, 32, outputBin) fmt.Printf(【input】:%v 【output】:%v (%v)\n, input, output, outputBin) } fmt.Printf(\n\n\n) }两个值得关注的工程细节%0*v宽度格式化fmt.Sprintf(%0*v, 32, input)强制输出 32 位并保留前置 0。这一步至关重要——strconv.FormatUint转出的二进制串会丢弃前导 0例如示例 1 输入会丢 6 个 0不做补齐就无法与题目中“32 位串逐位对照”的验证方式对齐数值断言 二进制串打印双轨验证测试用例以数值43261596 → 964176192、4294967293 → 3221225471作为正确答案锚点同时把输入/输出都打印成 32 位二进制串运行go test -v ./leetcode/0190.Reverse-Bits/时即可肉眼核对位序是否真正颠倒而不是仅仅数值相等。测试中的两个参数选取也覆盖了典型边界43261596是高位大量为 0 的普通值4294967293即0xFFFFFFFD是贴近uint32最大值4294967295的高位全 1 值恰好对应题目 Note 中“有符号语言下即 -3”的极端场景。仓库级的验证方式见 gotest.sh其核心命令为go test -covermodeatomic -coverprofilecoverage.txt ./leetcode/...该脚本对./leetcode/...所有题解包一次性生成合法的覆盖率 profile注释中说明Go 1.10 支持对多个包一次性-coverprofile可避免旧式“逐包 cat 追加”导致的重复mode: atomic头被 Codecov 误判为 0% 覆盖率覆盖率结果落地在仓库根的 coverage.txt。也就是说本篇展示的题解是被仓库 CI 全量回归覆盖的而非孤立示例。Go 视角下的“无符号整数”说明为什么 Java 的注意事项在 Go 中自动消失原题 Note 提醒Java 没有无符号整数类型输入输出会以int给出例如示例 2 输入是-3、输出是-1073741825但由于补码表示下位模式相同实现不受影响。对照仓库实现可以看到 Go 的处理方式更直接函数签名直接写uint324294967293在 Go 里是合法的uint32常量0xFFFFFFFD不存在“超出int范围要转成 -3”的问题源码中唯一的位运算链、、|、全部作用于uint32对无符号类型是逻辑右移行为确定测试文件中把uint32提升为uint64再交给strconv.FormatUint(_, 2)是为了得到一个无符号的 64 位容器来打印二进制串这也是 Go 中“安全打印无符号二进制”的惯用手法。因此题目中那段“语言无关性”说明对 Go 解法的实际含义是你不需要写任何兼容代码uint32语义与题目完全一致而算法本身32 次移位取位在 C、Java配与 0xFFFFFFFFL技巧中同样成立。延伸位反转背后的通用位技巧这道题属于仓库主 README.md 中标记为“✅ 已完成”的 Bit Manipulation位运算专题。README 的 Bit Manipulation 小节 汇总了本仓库位运算题解常用的技巧与 190 题直接相关的是Get the n-th bit of x (0 or 1): (x n) 1 // 190 题的 num1 就是 n0 的特例 x 1 1 测试 x 是否为奇数X 1 1 x (x - 1) 清除最低位的 1LSB x -x 孤立最低位的 1190 题的num 1正是“(x 0) 1”的特例而“循环右移 取位”的骨架也可以迁移到其他位操作题如仓库中的 191. Number of 1 Bits、461. Hamming Distance 等同样依赖(x n) 1与x x-1技巧。若要在面试中进一步压缩 190 题的常数常见优化是“分块反转”按 8/16 位分组查表或分步 掩码再拼接但从当前仓库源码结构看作者选择了最直白的 32 次循环写法——32 次恒定迭代本身就是 O(1)可读性优先这也是该仓库“严格遵循 Google Golang Style Guide”风格的体现。小结要素内容依据算法循环 32 次res res1 \| num1; num 1190. Reverse Bits.go复杂度O(1) 时间恒定 32 次迭代、O(1) 空间源码循环上界为常量 32测试锚点43261596 → 964176192、4294967293 → 3221225471均打印 32 位二进制串核对190. Reverse Bits_test.go验证方式go test -v ./leetcode/0190.Reverse-Bits/仓库级go test ./leetcode/...生成覆盖率gotest.sh、coverage.txt语言要点Go 的uint32原生匹配“32 位无符号整数”逻辑右移无符号扩展顾虑源码类型签名与题目 Note 对照这篇题解的价值不仅在于一道 Easy 题的 8 行代码更展示了 LeetCode-Go 仓库的完整题解范式README 存题面与思路、Go 文件存最小可运行实现、_test.go用题目原始示例做回归锚点三者配合并被覆盖率脚本统一校验。【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考