3370. Smallest Number With All Set Bits
Problem Description
You are given a positive integer n
. Your task is to find the smallest number x
that satisfies two conditions:
x
must be greater than or equal ton
(i.e.,x >= n
)- The binary representation of
x
must contain only set bits (all 1s, no 0s)
In other words, you need to find the smallest number that is at least n
and whose binary representation consists entirely of 1s.
For example:
- Numbers with only set bits in binary:
1
(binary: 1),3
(binary: 11),7
(binary: 111),15
(binary: 1111),31
(binary: 11111), etc. - If
n = 5
, the answer would be7
because:7
in binary is111
(all set bits)7 >= 5
- Numbers smaller than
7
with all set bits are3
(binary: 11) and1
(binary: 1), but both are less than5
The pattern of numbers with all set bits follows the sequence: 2^k - 1
where k
is a positive integer (1, 3, 7, 15, 31, 63, 127, ...).
Intuition
To understand the solution, let's first recognize what numbers have only set bits in their binary representation. These are numbers like 1
(binary: 1), 3
(binary: 11), 7
(binary: 111), 15
(binary: 1111), and so on. Notice a pattern here - these numbers are always one less than a power of 2:
1 = 2^1 - 1
3 = 2^2 - 1
7 = 2^3 - 1
15 = 2^4 - 1
31 = 2^5 - 1
Why does this pattern exist? When we have a power of 2 like 8
(binary: 1000), subtracting 1 gives us 7
(binary: 111). The subtraction causes a cascade effect where the single 1
bit becomes 0
and all positions to its right become 1
.
Now, to find the smallest such number that is greater than or equal to n
, we need to find the smallest power of 2, let's call it x
, such that x - 1 >= n
. This is equivalent to finding the smallest x
where x > n
.
The approach becomes clear: start with x = 1
(which is 2^0
) and keep doubling it (left shifting by 1 is the same as multiplying by 2) until x - 1
becomes greater than or equal to n
. At each step:
x = 1
gives usx - 1 = 0
x = 2
gives usx - 1 = 1
x = 4
gives usx - 1 = 3
x = 8
gives usx - 1 = 7
x = 16
gives usx - 1 = 15
We keep going until we find the first x
where x - 1 >= n
, and that x - 1
is our answer.
Learn more about Math patterns.
Solution Approach
The implementation uses bit manipulation to efficiently find the answer. Here's how the algorithm works step by step:
-
Initialize
x = 1
: We start with the smallest power of 2, which is2^0 = 1
. -
Loop with condition
while x - 1 < n
: We continue as long asx - 1
is still less thann
. This means the current value ofx - 1
(which has all set bits) is not yet large enough to be our answer. -
Left shift operation
x <<= 1
: In each iteration, we left shiftx
by 1 position. This is equivalent to multiplyingx
by 2, moving us to the next power of 2:- First iteration:
x = 1
becomesx = 2
- Second iteration:
x = 2
becomesx = 4
- Third iteration:
x = 4
becomesx = 8
- And so on...
- First iteration:
-
Return
x - 1
: Once the loop exits, we have found the smallest power of 2 wherex - 1 >= n
. Sincex
is a power of 2,x - 1
will have all bits set in its binary representation.
Example walkthrough with n = 5
:
- Start:
x = 1
, checkx - 1 = 0 < 5
, continue - After shift:
x = 2
, checkx - 1 = 1 < 5
, continue - After shift:
x = 4
, checkx - 1 = 3 < 5
, continue - After shift:
x = 8
, checkx - 1 = 7 >= 5
, exit loop - Return
7
The time complexity is O(log n)
because we need at most log₂(n) + 1
iterations to find the answer. The space complexity is O(1)
as we only use a single variable x
.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with n = 10
to find the smallest number with all set bits that is greater than or equal to 10.
Step-by-step process:
-
Initialize: Start with
x = 1
- Check:
x - 1 = 0
, is0 >= 10
? No, continue.
- Check:
-
First iteration: Left shift
x
→x = 2
- Binary:
x = 10₂
- Check:
x - 1 = 1
, is1 >= 10
? No, continue. - Note:
1
in binary is1₂
(all set bits, but too small)
- Binary:
-
Second iteration: Left shift
x
→x = 4
- Binary:
x = 100₂
- Check:
x - 1 = 3
, is3 >= 10
? No, continue. - Note:
3
in binary is11₂
(all set bits, but still too small)
- Binary:
-
Third iteration: Left shift
x
→x = 8
- Binary:
x = 1000₂
- Check:
x - 1 = 7
, is7 >= 10
? No, continue. - Note:
7
in binary is111₂
(all set bits, but still not enough)
- Binary:
-
Fourth iteration: Left shift
x
→x = 16
- Binary:
x = 10000₂
- Check:
x - 1 = 15
, is15 >= 10
? Yes, stop! - Note:
15
in binary is1111₂
(all set bits, and it's >= 10)
- Binary:
Result: Return x - 1 = 15
Verification:
15
in binary is1111₂
✓ (all bits are set)15 >= 10
✓ (satisfies the minimum requirement)- The previous candidate
7
(binary:111₂
) was less than 10, so 15 is indeed the smallest valid answer
The algorithm efficiently finds that we need 4 set bits to create a number at least as large as 10, resulting in the answer 15.
Solution Implementation
1class Solution:
2 def smallestNumber(self, n: int) -> int:
3 # Initialize power_of_two to 1 (2^0)
4 power_of_two = 1
5
6 # Keep doubling power_of_two until (power_of_two - 1) >= n
7 # This finds the smallest power of 2 such that (2^k - 1) >= n
8 while power_of_two - 1 < n:
9 power_of_two <<= 1 # Multiply by 2 using left bit shift
10
11 # Return 2^k - 1, which is a number with all bits set to 1
12 # For example: if power_of_two = 8 (binary 1000), return 7 (binary 111)
13 return power_of_two - 1
14
1class Solution {
2 public int smallestNumber(int n) {
3 // Initialize power of 2 starting from 2^0 = 1
4 int powerOfTwo = 1;
5
6 // Keep doubling the power of 2 until (powerOfTwo - 1) is at least n
7 // This finds the smallest k such that 2^k - 1 >= n
8 while (powerOfTwo - 1 < n) {
9 // Left shift by 1 is equivalent to multiplying by 2
10 // powerOfTwo becomes 2, 4, 8, 16, 32, ...
11 powerOfTwo <<= 1;
12 }
13
14 // Return 2^k - 1, which is a number with all k bits set to 1
15 // Examples: 1 (2^1-1), 3 (2^2-1), 7 (2^3-1), 15 (2^4-1), ...
16 return powerOfTwo - 1;
17 }
18}
19
1class Solution {
2public:
3 int smallestNumber(int n) {
4 // Find the smallest number of the form (2^k - 1) that is >= n
5 // These are numbers with all bits set: 1, 3, 7, 15, 31, 63, 127...
6
7 // Start with 2^0 = 1
8 int powerOfTwo = 1;
9
10 // Keep doubling the power of 2 until (powerOfTwo - 1) >= n
11 // Left shift by 1 is equivalent to multiplying by 2
12 while (powerOfTwo - 1 < n) {
13 powerOfTwo <<= 1; // powerOfTwo = powerOfTwo * 2
14 }
15
16 // Return the number with all bits set (2^k - 1)
17 return powerOfTwo - 1;
18 }
19};
20
1/**
2 * Finds the smallest number with all bits set (all 1s in binary representation)
3 * that is greater than or equal to n.
4 *
5 * @param n - The input number to find the smallest all-bits-set number for
6 * @returns The smallest number with all bits set that is >= n
7 */
8function smallestNumber(n: number): number {
9 // Start with 1 (binary: 1)
10 let powerOfTwo = 1;
11
12 // Keep doubling (left shift by 1) until (powerOfTwo - 1) >= n
13 // This finds the smallest power of 2 such that (2^k - 1) >= n
14 // Example: if n = 5, we need 2^3 = 8, so result is 8 - 1 = 7 (binary: 111)
15 while (powerOfTwo - 1 < n) {
16 powerOfTwo <<= 1; // Equivalent to powerOfTwo *= 2
17 }
18
19 // Return the number with all bits set (e.g., 7 = 111, 15 = 1111, etc.)
20 return powerOfTwo - 1;
21}
22
Time and Space Complexity
The time complexity is O(log n)
, and the space complexity is O(1)
.
Time Complexity Analysis:
The algorithm starts with x = 1
and repeatedly doubles it using left shift operation (x <<= 1
) until x - 1 >= n
. Since x
doubles in each iteration, the number of iterations required is proportional to the number of times we need to double 1 to exceed n
. This requires approximately log₂(n)
iterations, resulting in O(log n)
time complexity.
Space Complexity Analysis:
The algorithm only uses a single variable x
to store the intermediate values, regardless of the input size n
. No additional data structures or recursive calls are used, making the space complexity O(1)
(constant space).
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Integer Overflow for Large Values of n
When dealing with very large values of n
, the left shift operation power_of_two <<= 1
can cause integer overflow if not handled properly. In some programming languages with fixed integer sizes, this could lead to unexpected behavior or wrap-around.
Example of the issue:
- If
n
is close to the maximum integer value, continuously doublingpower_of_two
might exceed the integer limit. - In languages like C++ or Java with fixed integer sizes, this could cause undefined behavior or negative values.
Solution:
class Solution:
def smallestNumber(self, n: int) -> int:
# Check if n is already a number with all bits set
# This avoids unnecessary iterations for edge cases
if n & (n + 1) == 0:
return n
# Find the position of the most significant bit in n
bit_position = n.bit_length()
# Calculate 2^(bit_position) - 1
result = (1 << bit_position) - 1
# If result is less than n, we need the next power of 2
if result < n:
result = (1 << (bit_position + 1)) - 1
return result
2. Misunderstanding the Problem Requirements
A common mistake is thinking that we need to find a number whose binary representation is the same length as n
's binary representation, rather than finding the smallest number with all set bits that is >= n.
Incorrect approach:
# WRONG: This tries to set all bits in n's binary representation
def incorrectSolution(n: int) -> int:
result = n
while result & (result + 1) != 0: # Check if all bits are set
result |= (result + 1) # This doesn't give the correct answer
return result
Correct understanding: We need the smallest number from the sequence 1, 3, 7, 15, 31, 63, 127... that is >= n.
3. Off-by-One Error in Loop Condition
Using power_of_two < n
instead of power_of_two - 1 < n
in the while loop condition would cause incorrect results.
Incorrect version:
# WRONG: This will return a larger number than necessary
def incorrectLoop(n: int) -> int:
power_of_two = 1
while power_of_two < n: # Wrong condition!
power_of_two <<= 1
return power_of_two - 1
# For n=4, this returns 7 instead of 7 (happens to be correct)
# For n=3, this returns 3 instead of 3 (correct by chance)
# For n=2, this returns 3 instead of 3 (correct)
# For n=1, this returns 0 instead of 1 (WRONG!)
The correct condition power_of_two - 1 < n
ensures we find the smallest power of 2 where subtracting 1 gives us a value >= n.
In a binary min heap, the maximum element can be found in:
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!