231. Power of Two - Explanation
Description
You are given an integer n, return true if it is a power of two. Otherwise, return false.
An integer n is a power of two, if there exists an integer x such that n == (2^x).
Example 1:
Input: n = 1
Output: trueExplanation: (2^0) is 1.
Example 2:
Input: n = 8
Output: trueExplanation: (2^3) is 8.
Example 3:
Input: n = 12
Output: falseConstraints:
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- Bit Manipulation - Understanding binary representation of numbers and bitwise operators (AND, OR, shifts) is essential for the optimal solutions
- Recursion - The recursive approach divides the problem by 2 at each step until reaching the base case
- Two's Complement - Understanding how negative numbers are represented helps explain why
n & (-n)isolates the lowest set bit
1. Brute Force
Intuition
We can generate all powers of two by starting from 1 and repeatedly multiplying by 2. If we reach exactly n, then n is a power of two. If we exceed n without matching it, then it's not.
Algorithm
- If
nis less than or equal to0, returnfalse. - Start with
x = 1. - While
xis less thann, multiplyxby2. - Return
trueifxequalsn,falseotherwise.
Time & Space Complexity
- Time complexity:
- Space complexity:
2. Recursion
Intuition
A number is a power of two if we can repeatedly divide it by 2 until we reach 1. If at any point the number is odd (and not 1), it cannot be a power of two.
This recursive approach reduces the problem by half at each step.
Algorithm
- If
nequals1, returntrue(2^0 = 1). - If
nis less than or equal to0, ornis odd, returnfalse. - Recursively check if
n / 2is a power of two.
Time & Space Complexity
- Time complexity:
- Space complexity: for recursion stack.
3. Iteration
Intuition
The same logic as recursion, but implemented with a loop. We keep dividing by 2 (or right-shifting by 1) as long as the number is even. If we end up with 1, the original number was a power of two.
Algorithm
- If
nis less than or equal to0, returnfalse. - While
nis even (divisible by2), right-shiftnby1. - Return
trueifnequals1,falseotherwise.
Time & Space Complexity
- Time complexity:
- Space complexity:
4. Bit Manipulation - I
Intuition
In two's complement representation, -n flips all bits of n and adds 1. For a power of two (which has exactly one set bit), n & (-n) isolates the lowest set bit. If n is a power of two, this equals n itself since there's only one bit set.
Algorithm
- Check that
nis positive. - Compute
n & (-n)to isolate the lowest set bit. - Return
trueif this equalsn, meaningnhas exactly one set bit.
Time & Space Complexity
- Time complexity:
- Space complexity:
5. Bit Manipulation - II
Intuition
Powers of two in binary have exactly one bit set (1, 10, 100, 1000, ...). Subtracting 1 from such a number flips all bits from the rightmost set bit onward. For example, 8 (1000) minus 1 equals 7 (0111).
ANDing n with n - 1 clears the lowest set bit. If n is a power of two, this results in 0 since there was only one bit to clear.
Algorithm
- Check that
nis positive. - Compute
n & (n - 1)to clear the lowest set bit. - Return
trueif the result is0, meaningnhad exactly one set bit.
Time & Space Complexity
- Time complexity:
- Space complexity:
6. Math
Intuition
The largest power of two that fits in a 32-bit signed integer is 2^30 (since 2^31 exceeds the positive range). Any smaller power of two must divide evenly into 2^30.
If n is a power of two, then 2^30 mod n equals 0. If n is not a power of two, the division will have a remainder.
Algorithm
- Check that
nis positive. - Compute
(1 << 30) % n(i.e.,2^30 mod n). - Return
trueif the result is0.
Time & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Forgetting to Handle Non-Positive Numbers
A common mistake is forgetting that n must be strictly positive. Zero and negative numbers cannot be powers of two, but the bit manipulation tricks like n & (n - 1) == 0 will incorrectly return true for n = 0. Always check n > 0 before applying bit operations.
Integer Overflow in Iterative Approaches
When iteratively multiplying by 2 (e.g., x *= 2), the variable can overflow if using a 32-bit integer type. In languages like Java or C++, use a long or long long type for the accumulator to avoid wrapping around to negative values before reaching large inputs like 2^30.
Sign in to join the discussion