將 32 位無符號整數的位元順序完全反轉(bit 0 ↔ bit 31, bit 1 ↔ bit 30, ...)。
以 16、8、4、2、1 為單位逐層交換,利用位元遮罩隔離區塊:
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
n = (n >> 16) | (n << 16); // 交換高低 16 位
n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8); // 交換位元組
n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4); // 交換 4 位
n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2); // 交換 2 位
n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1); // 交換相鄰位
return n;
}
};
每步位移補零(無符號右移),遮罩確保只交換目標區塊。
class Solution {
public:
uint32_t swapBits(uint32_t n, int i, int j) {
int lo = (n >> i) & 1;
int hi = (n >> j) & 1;
if (lo != hi) {
n ^= (1u << i) | (1u << j); // 異或翻轉:0^1=1, 1^1=0
}
return n;
}
uint32_t reverseBits(uint32_t n) {
for (int i = 0; i < 16; i++) {
n = swapBits(n, i, 31 - i);
}
return n;
}
};
利用異或性質:x ^ 1 = ~x,x ^ 0 = x。僅當兩位不同時翻轉。
預計算 0~255 所有 8 位反轉結果,查表組合:
class Solution {
uint8_t table[256];
bool inited = false;
void init() {
for (int i = 0; i < 256; i++) {
uint8_t x = i, rev = 0;
for (int j = 0; j < 8; j++) {
rev = (rev << 1) | (x & 1);
x >>= 1;
}
table[i] = rev;
}
inited = true;
}
public:
uint32_t reverseBits(uint32_t n) {
if (!inited) init();
return (table[n & 0xff] << 24) |
(table[(n >> 8) & 0xff] << 16) |
(table[(n >> 16) & 0xff] << 8) |
(table[(n >> 24) & 0xff]);
}
};
| 方法 | 操作數 | 分支 | 適用場景 |
|---|---|---|---|
| 分治合併 | ~20 位元運算 | 無 | 單次調用、極致效能 |
| 兩兩交換 | 16 次迴圈 | 16 次判斷 | 教學、可讀性優先 |
| 查表法 | 4 次查表 + 移位 | 無 | 高頻調用(需一次性初始化) |