题目描述#

欸,这题听着就带感——颠倒给定的 32 位整数的二进制位。也就是说,把这个数当成一串 32 位的 0/1,然后整串首尾翻转:原来的第 0 位变成第 31 位,第 1 位变成第 30 位,以此类推,再把翻转后的二进制读成一个新数返回。

思路#

咱第一眼看,这题的关键词是"逐位搬运"。既然要把低位翻到高位,那就一位一位地从 n 的最低位取出来,塞到答案 ans 的最低位,再让 ans 整体左移腾位置——这样最先取出的位会被一路顶到最高位去,正好实现了翻转。

具体每一轮干两件事:

  1. ans = ans<<1 | (n & 1):先把 ans 左移一位(原来的内容整体往高位挪、最低位空出来),再用 n & 1 取出 n 当前的最低位,用按位或 | 填进那个空位。
  2. n = n >> 1:把 n 右移一位,让下一位变成新的最低位,等着下一轮被取走。

循环正好 32 次,对应 32 个二进制位。本姑娘画个小账本帮你记:第 1 轮取到的是 n 的最低位,但它被后面 31 次左移一路抬到了第 31 位(最高位);最后一轮取到的是 n 的最高位,落在第 0 位(最低位)——首尾就这么对调过来啦,干净利落!

ans <<= 1ans | bit 的先后顺序也有讲究:必须先左移、再或入新位,要是反了,新位就会被下一次左移又顶走一格,全乱套。

知识边界#

  • 取最低位n & 1 拿到二进制最末位(0 或 1),是逐位处理的标配手法。
  • 右移送位n >> 1 丢掉已处理的最低位,把下一位推到末尾。这里题目语境是无符号的 32 位,每位非 0 即 1,不必纠结符号位。
  • 左移腾位 + 或入ans = ans<<1 | (n&1) 是"反转/收集二进制位"的经典组合,先移后或的顺序不能调换——容易踩坑哦。
  • 固定循环 32 次:位宽是题目写死的 32,所以循环次数是常数,时间复杂度 $O(1)$(与数值大小无关)。
  • 运算符优先级:Go 里 << 优先级高于 |,所以 ans<<1 | (n & 1) 等价于 (ans<<1) | (n&1),不加括号也对;但给 n & 1 套个括号读起来更稳妥。

代码#

这段咱也原样保留,循环 32 次逐位搬运:

func reverseBits(n int) int {
    ans := 0

    for i := 0; i < 32; i++ {
        ans = ans<<1 | (n & 1)
        n = n >> 1
    }
    return ans
}

好啦,位运算这个新章节就先开这两道~咱去整理今天的照片咯,下次再来收拾更刁钻的位操作题!

本站总访问量  ·  访客数
你的IP 获取中…