Reverse bits of a given 32 bits unsigned integer.
Note:
-3
and the output represents the signed integer -1073741825
.Example 1:
Input: n = 00000010100101000001111010011100 Output: 964176192 (00111001011110000010100101000000) Explanation: The input binary string 00000010100101000001111010011100 represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000.
Example 2:
Input: n = 11111111111111111111111111111101 Output: 3221225471 (10111111111111111111111111111111) Explanation: The input binary string 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?
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The core idea is to flip the order of the bits in the given number. We'll examine each bit individually, determine its new position, and place it there.
Here's how the algorithm would work step-by-step:
def reverse_bits_brute_force(number):
reversed_number = 0
for bit_index in range(32):
# Check if the current bit is set.
if (number >> bit_index) & 1:
# Move the current bit to its reversed position.
reversed_number |= 1 << (31 - bit_index)
return reversed_number
The key to efficiently reversing the bits of a number is to swap pairs of bits strategically. Instead of individually moving each bit, we'll focus on swapping bits across the number in a series of stages to achieve the reversal quickly.
Here's how the algorithm would work step-by-step:
def reverse_bits(number):
reversed_number = 0
# Swap adjacent bits
number = (number & 0x55555555) << 1 | (number & 0xAAAAAAAA) >> 1
# Swap pairs of bits that are two positions apart
number = (number & 0x33333333) << 2 | (number & 0xCCCCCCCC) >> 2
# Swap nibbles (4 bits)
number = (number & 0x0F0F0F0F) << 4 | (number & 0xF0F0F0F0) >> 4
# Swap bytes (8 bits)
number = (number & 0x00FF00FF) << 8 | (number & 0xFF00FF00) >> 8
# Swap 16-bit halves
number = (number & 0x0000FFFF) << 16 | (number & 0xFFFF0000) >> 16
reversed_number = number
return reversed_number
Case | How to Handle |
---|---|
Input n is 0 | The reversed bits of 0 is also 0, so the algorithm should return 0. |
Input n is a power of 2 (e.g., 1, 2, 4, 8) | This tests the shifting and bit manipulation logic to ensure correct reversal. |
Input n is 2^31 - 1 (maximum positive signed 32-bit integer represented as unsigned) | Check for integer overflow during bit manipulation. |
Input n is 2^32 - 1 (all bits are 1) | This tests the case where all bits need to be flipped. |
Input n has leading zeros (already reversed) | The algorithm should still correctly reverse the bits, even if the input seems pre-processed. |
Input n is close to the maximum unsigned 32 bit integer (2^32 - 2 or 2^32 - 3) | This tests edge cases regarding the upper limit and bit manipulation correctness when the MSB is flipped. |
Input n contains alternating bits (e.g., 010101... or 101010...) | Tests the algorithm's ability to correctly flip a pattern. |
Algorithm performs excessive bit shifts or iterations | Verify performance, the algorithm should complete in a fixed number of operations proportional to the bit size (32). |