LeetCode 1009 - Complement of Base 10 Integer
This problem asks us to compute the complement of a base-10 integer by flipping every bit in its binary representation. For instance, if the input n is 5, its binary form is 101. Flipping each 0 to 1 and each 1 to 0 produces 010, which equals 2 in decimal.
Difficulty: 🟢 Easy
Topics: Bit Manipulation
Solution
Problem Understanding
This problem asks us to compute the complement of a base-10 integer by flipping every bit in its binary representation. For instance, if the input n is 5, its binary form is 101. Flipping each 0 to 1 and each 1 to 0 produces 010, which equals 2 in decimal. The input is guaranteed to be a non-negative integer less than 10^9. The output should also be a non-negative integer, representing the decimal value of the binary complement.
The problem is straightforward in concept but requires careful handling of binary operations. Edge cases to consider include n = 0, where the binary is 0 and its complement should be 1, and numbers that are all 1s in binary, like 7 (111), whose complement is 0.
Key observations include that we only need to flip bits up to the most significant 1 bit, ignoring leading zeros.
Approaches
The brute-force approach involves converting the number to its binary string, flipping each bit manually, and then converting back to decimal. This works correctly but involves string manipulation and extra space, which is unnecessary for this problem.
The optimal approach relies on bit manipulation. The insight is that to flip all bits of n, we can XOR n with a mask of the same length that has all bits set to 1. For example, for n = 5 (101), the mask is 111 in binary (or 7 in decimal). XORing 5 ^ 7 produces 2, which is the complement.
| Approach | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Brute Force | O(log n) | O(log n) | Convert to binary string, flip characters, convert back |
| Optimal | O(log n) | O(1) | Compute a mask with all 1s up to most significant bit, XOR with n |
Algorithm Walkthrough
- Check if
nis zero. If it is, return1because the complement of0is1. - Initialize a variable
maskto0. This will hold a sequence of1s the same length as the binary representation ofn. - Initialize a copy of
nin a variabletemp. - While
tempis greater than0, shiftmaskleft by one and add1. Simultaneously, shifttempright by one. This builds a mask of all1s with the same number of bits asn. - XOR
nwithmask. This flips all the bits ofn. - Return the result of the XOR operation.
Why it works: The XOR operation flips bits where the mask has 1s and leaves bits as 0 unchanged. By constructing a mask that has 1s only in the positions of the original number's bits, we flip exactly the bits that are significant, ignoring leading zeros. This guarantees correctness.
Python Solution
class Solution:
def bitwiseComplement(self, n: int) -> int:
if n == 0:
return 1
mask = 0
temp = n
while temp > 0:
mask = (mask << 1) | 1
temp >>= 1
return n ^ mask
The Python solution first handles the special case n = 0. It then constructs the mask by repeatedly left-shifting and adding 1 until all bits in n are accounted for. Finally, it flips the bits using XOR and returns the result.
Go Solution
func bitwiseComplement(n int) int {
if n == 0 {
return 1
}
mask := 0
temp := n
for temp > 0 {
mask = (mask << 1) | 1
temp >>= 1
}
return n ^ mask
}
The Go implementation mirrors the Python logic closely. Bitwise operations in Go behave similarly to Python. The only difference is type declarations, but since n is guaranteed to be within int range, there are no overflow concerns.
Worked Examples
Example 1: n = 5
| Step | temp | mask | n ^ mask |
|---|---|---|---|
| Initial | 5 | 0 | - |
| Iteration 1 | 2 | 1 | - |
| Iteration 2 | 1 | 3 | - |
| Iteration 3 | 0 | 7 | 2 |
Result is 2.
Example 2: n = 7
| Step | temp | mask | n ^ mask |
|---|---|---|---|
| Initial | 7 | 0 | - |
| Iteration 1 | 3 | 1 | - |
| Iteration 2 | 1 | 3 | - |
| Iteration 3 | 0 | 7 | 0 |
Result is 0.
Example 3: n = 10
| Step | temp | mask | n ^ mask |
|---|---|---|---|
| Initial | 10 | 0 | - |
| Iteration 1 | 5 | 1 | - |
| Iteration 2 | 2 | 3 | - |
| Iteration 3 | 1 | 7 | - |
| Iteration 4 | 0 | 15 | 5 |
Result is 5.
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(log n) | Each loop iteration shifts temp right, which happens log2(n) times |
| Space | O(1) | Only constant variables mask and temp are used |
The complexity is efficient because we only iterate over the number of bits in n, which grows logarithmically with the size of the number.
Test Cases
# Provided examples
assert Solution().bitwiseComplement(5) == 2 # "101" -> "010"
assert Solution().bitwiseComplement(7) == 0 # "111" -> "000"
assert Solution().bitwiseComplement(10) == 5 # "1010" -> "0101"
# Edge cases
assert Solution().bitwiseComplement(0) == 1 # special case
assert Solution().bitwiseComplement(1) == 0 # single-bit number
assert Solution().bitwiseComplement(2) == 1 # "10" -> "01"
# Large numbers
assert Solution().bitwiseComplement(999999999) == 295279706 # test high end of constraint
| Test | Why |
|---|---|
| 5 | Normal small odd number |
| 7 | All ones in binary, result is zero |
| 10 | Even number with alternating bits |
| 0 | Edge case for zero |
| 1 | Single-bit number edge case |
| 2 | Smallest multi-bit number |
| 999999999 | Large number stress test |
Edge Cases
- n = 0: The binary is a single
0. A naive implementation flipping bits of zero might return zero, but the complement should be1. Our solution explicitly handles this case. - n is a power of two minus one: Numbers like
1,3,7,15are all ones in binary. Flipping their bits produces0. This tests that the mask construction correctly accounts for numbers with no zeros in their binary representation. - Large numbers: Numbers close to
10^9test that the solution handles many bits efficiently and does not rely on string conversion or recursion, which could be slow or memory intensive. The bitwise method handles this gracefully.