Reverse bits of a given 32 bits unsigned integer.
Note:
-3
and the output represents the signed integer -1073741825
.Examples:
n = 00000010100101000001111010011100
964176192
(00111001011110000010100101000000
)00000010100101000001111010011100
represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000
.n = 11111111111111111111111111111101
3221225471
(10111111111111111111111111111111
)11111111111111111111111111111101
represents the unsigned integer 4294967293, so return 3221225471 which its binary representation is 10111111111111111111111111111111
.Constraints:
32
Follow up: If this function is called many times, how would you optimize it?
Let's explore how to reverse the bits of a 32-bit unsigned integer.
A straightforward approach is to iterate through the 32 bits, swapping the bits from the start and end towards the middle. This involves extracting each bit and placing it at the opposite end.
def reverse_bits_naive(n):
result = 0
for i in range(32):
if (n >> i) & 1:
result |= 1 << (31 - i)
return result
Explanation:
result
to 0.i = 0
to 31
.i
, we check if the i
-th bit of n
is set.(31 - i)
-th bit of result
.result
.A more efficient method involves using bit manipulation techniques to reverse the bits. This approach minimizes the number of operations required.
def reverse_bits_optimal(n):
n = (n >> 16) | (n << 16)
n = ((n & 0xFF00FF00) >> 8) | ((n & 0x00FF00FF) << 8)
n = ((n & 0xF0F0F0F0) >> 4) | ((n & 0x0F0F0F0F) << 4)
n = ((n & 0xCCCCCCCC) >> 2) | ((n & 0x33333333) << 2)
n = ((n & 0xAAAAAAAA) >> 1) | ((n & 0x55555555) << 1)
return n
Explanation:
If this function is called many times, we can optimize it using a lookup table (cache). We can precompute the reversed values for all possible 8-bit integers (0-255) and store them in a cache. Then, for any 32-bit integer, we can split it into four 8-bit chunks, look up the reversed value for each chunk in the cache, and combine the reversed chunks to form the final reversed integer.
class Solution:
def __init__(self):
self.cache = {}
def reverse_bits_cached(self, n):
result = 0
for i in range(4):
byte = (n >> (i * 8)) & 0xFF
reversed_byte = self.reverse_byte(byte)
result |= reversed_byte << ((3 - i) * 8)
return result
def reverse_byte(self, byte):
if byte not in self.cache:
reversed_byte = 0
for i in range(8):
if (byte >> i) & 1:
reversed_byte |= 1 << (7 - i)
self.cache[byte] = reversed_byte
return self.cache[byte]
Explanation: