LeetCode 693: Binary Number with Alternating Bits
Check whether every adjacent bit in a positive integer's binary representation is different.
Problem Restatement
We are given a positive integer n.
We need to check whether its binary representation has alternating bits.
That means every pair of adjacent bits must be different. The official statement says two adjacent bits should always have different values. For example, 5 is valid because its binary representation is 101, while 7 is invalid because its binary representation is 111.
Input and Output
| Item | Meaning |
|---|---|
| Input | A positive integer n |
| Output | true if adjacent bits alternate, otherwise false |
| Constraint | 1 <= n <= 2^31 - 1 |
| Binary rule | No two adjacent bits may be equal |
Example function shape:
def hasAlternatingBits(n: int) -> bool:
...
Examples
Example 1:
n = 5
Binary:
101
Adjacent pairs:
| Pair | Different? |
|---|---|
1, 0 |
Yes |
0, 1 |
Yes |
Answer:
True
Example 2:
n = 7
Binary:
111
The first two adjacent bits are both 1.
Answer:
False
Example 3:
n = 10
Binary:
1010
Every adjacent pair is different.
Answer:
True
First Thought: Convert to Binary String
The simplest solution is to convert n to its binary representation as a string.
Then check adjacent characters.
bin(n)
returns a string like:
0b101
The first two characters are the prefix 0b, so we remove them with:
bin(n)[2:]
Then scan the string.
Algorithm
- Convert
nto a binary string. - For each index
ifrom1to the end:- If
bits[i] == bits[i - 1], returnFalse.
- If
- If no equal adjacent pair is found, return
True.
Correctness
The binary string contains the bits of n in order from most significant to least significant.
The algorithm checks every adjacent pair in that string.
If it finds two equal adjacent bits, then the binary representation does not alternate, so returning False is correct.
If the loop finishes, every adjacent pair has different bits. That is exactly the definition of alternating bits, so returning True is correct.
Complexity
Let w be the number of bits in n.
| Metric | Value | Why |
|---|---|---|
| Time | O(w) |
We scan the binary representation once |
| Space | O(w) |
The binary string stores all bits |
Since n <= 2^31 - 1, w <= 31, so this is effectively constant for this problem.
Implementation
class Solution:
def hasAlternatingBits(self, n: int) -> bool:
bits = bin(n)[2:]
for i in range(1, len(bits)):
if bits[i] == bits[i - 1]:
return False
return True
Code Explanation
This line converts the number into binary form:
bits = bin(n)[2:]
For example:
bin(10)[2:] == "1010"
The loop compares each bit with the previous bit:
for i in range(1, len(bits)):
If two adjacent bits are equal:
if bits[i] == bits[i - 1]:
return False
the pattern is not alternating.
If no equal adjacent bits are found:
return True
then the number has alternating bits.
Bit Manipulation Version
We can also avoid creating a string.
Read the bits from right to left.
Store the previous bit, then compare it with the next bit.
class Solution:
def hasAlternatingBits(self, n: int) -> bool:
previous = n & 1
n >>= 1
while n:
current = n & 1
if current == previous:
return False
previous = current
n >>= 1
return True
Here:
n & 1
extracts the last bit.
And:
n >>= 1
removes the last bit.
Testing
def run_tests():
s = Solution()
assert s.hasAlternatingBits(5) is True
assert s.hasAlternatingBits(7) is False
assert s.hasAlternatingBits(11) is False
assert s.hasAlternatingBits(10) is True
assert s.hasAlternatingBits(1) is True
assert s.hasAlternatingBits(2) is True
assert s.hasAlternatingBits(3) is False
assert s.hasAlternatingBits(21) is True
print("all tests passed")
run_tests()
Test meaning:
| Test | Binary | Expected | Why |
|---|---|---|---|
5 |
101 |
true |
Alternating |
7 |
111 |
false |
Adjacent 1s |
11 |
1011 |
false |
Ends with adjacent 1s |
10 |
1010 |
true |
Alternating |
1 |
1 |
true |
Single bit has no bad adjacent pair |
2 |
10 |
true |
Adjacent bits differ |
3 |
11 |
false |
Adjacent bits equal |
21 |
10101 |
true |
Alternating |