342. Power of Four
Problem Description
Given an integer n
, you need to determine if it is a power of four. Return true
if n
is a power of four, otherwise return false
.
A number n
is considered a power of four if there exists some integer x
such that n == 4^x
.
For example:
16
is a power of four because16 = 4^2
1
is a power of four because1 = 4^0
5
is not a power of four because there's no integerx
where4^x = 5
The solution uses bit manipulation to efficiently check this condition. The approach recognizes that powers of four have specific properties in their binary representation:
- They must be positive numbers
- They have exactly one
1
bit in their binary form (since4^x = 2^(2x)
, making them powers of two) - That single
1
bit must appear at an even position (bit positions 0, 2, 4, 6, etc.)
The code checks these conditions using:
n > 0
to ensure the number is positive(n & (n - 1)) == 0
to verify there's only one1
bit (property of powers of two)(n & 0xAAAAAAAA) == 0
to ensure the1
bit is at an even position (0xAAAAAAAA has1
s at all odd bit positions)
Intuition
The key insight starts with recognizing that any power of four can be expressed as 4^x = (2^2)^x = 2^(2x)
. This means every power of four is also a power of two, but not every power of two is a power of four.
Let's think about the binary representation of powers of four:
4^0 = 1
=0001
(bit position 0)4^1 = 4
=0100
(bit position 2)4^2 = 16
=10000
(bit position 4)4^3 = 64
=1000000
(bit position 6)
We notice a pattern: powers of four have exactly one 1
bit, and this bit always appears at even positions (0, 2, 4, 6, ...).
This leads us to a three-step verification process:
First, we need to ensure the number is positive since negative numbers and zero cannot be powers of four.
Second, we need to verify it's a power of two. The trick (n & (n - 1)) == 0
works because subtracting 1 from a power of two flips all the bits after the single 1
bit. For example, 8
is 1000
and 7
is 0111
. Their AND operation gives 0
. This only happens for powers of two.
Third, we need to distinguish powers of four from other powers of two. Since powers of four have their single 1
bit at even positions, we can use a mask that has 1
s at all odd positions. The hexadecimal 0xAAAAAAAA
represents the binary pattern 10101010...10101010
(32 bits with 1
s at odd positions). If our number is a power of four, its single 1
bit is at an even position, so ANDing with this mask will yield 0
.
By combining these three checks, we can efficiently determine if a number is a power of four using only bitwise operations.
Solution Approach
The solution uses bit manipulation to efficiently determine if a number is a power of four. The implementation consists of three key checks combined with logical AND operations:
Step 1: Check if the number is positive
n > 0
This ensures we're dealing with a valid candidate since powers of four must be positive integers.
Step 2: Verify the number is a power of two
(n & (n - 1)) == 0
This clever bit manipulation trick works because:
- For any power of two, there's exactly one
1
bit in its binary representation - When we subtract 1 from a power of two, all bits after the single
1
become1
, and the original1
becomes0
- Example:
16
is10000
, and15
is01111
. Their bitwise AND is00000
- This condition is only true for powers of two (and zero, which we've already excluded)
Step 3: Ensure the single 1
bit is at an even position
(n & 0xAAAAAAAA) == 0
The hexadecimal value 0xAAAAAAAA
represents a 32-bit mask with the pattern 10101010101010101010101010101010
:
- This mask has
1
bits at all odd positions (1, 3, 5, 7, ...) - Powers of four have their single
1
bit at even positions (0, 2, 4, 6, ...) - When we AND a power of four with this mask, the result is
0
because there's no overlap - Example:
16
is10000
(bit at position 4), AND with the mask gives0
The final solution combines all three conditions:
return n > 0 and (n & (n - 1)) == 0 and (n & 0xAAAAAAAA) == 0
This approach has O(1)
time complexity since we're performing a fixed number of bitwise operations, and O(1)
space complexity as we only use a constant amount of extra space.
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 two examples to see how the bit manipulation approach works.
Example 1: Is 16 a power of four?
First, let's convert 16 to binary: 16 = 0x00000010 = 00000000000000000000000000010000
Now let's check each condition:
-
Is n > 0?
- Yes, 16 > 0 ✓
-
Is (n & (n - 1)) == 0?
- n = 16 =
00000000000000000000000000010000
- n - 1 = 15 =
00000000000000000000000000001111
- n & (n - 1) =
00000000000000000000000000000000
= 0 ✓ - This confirms 16 is a power of two
- n = 16 =
-
Is (n & 0xAAAAAAAA) == 0?
- n = 16 =
00000000000000000000000000010000
(the 1 bit is at position 4, which is even) - 0xAAAAAAAA =
10101010101010101010101010101010
(1s at all odd positions) - n & 0xAAAAAAAA =
00000000000000000000000000000000
= 0 ✓ - The single 1 bit in 16 doesn't overlap with any odd position bits
- n = 16 =
All conditions pass, so 16 is a power of four (16 = 4²).
Example 2: Is 8 a power of four?
Convert 8 to binary: 8 = 0x00000008 = 00000000000000000000000000001000
Check each condition:
-
Is n > 0?
- Yes, 8 > 0 ✓
-
Is (n & (n - 1)) == 0?
- n = 8 =
00000000000000000000000000001000
- n - 1 = 7 =
00000000000000000000000000000111
- n & (n - 1) =
00000000000000000000000000000000
= 0 ✓ - This confirms 8 is a power of two
- n = 8 =
-
Is (n & 0xAAAAAAAA) == 0?
- n = 8 =
00000000000000000000000000001000
(the 1 bit is at position 3, which is odd) - 0xAAAAAAAA =
10101010101010101010101010101010
(1s at all odd positions) - n & 0xAAAAAAAA =
00000000000000000000000000001000
= 8 ≠ 0 ✗ - The single 1 bit in 8 overlaps with the odd position bit at position 3
- n = 8 =
The third condition fails, so 8 is not a power of four (it's 2³, not 4^x).
Solution Implementation
1class Solution:
2 def isPowerOfFour(self, n: int) -> bool:
3 # Check three conditions:
4 # 1. n > 0: Power of four must be positive
5 # 2. (n & (n - 1)) == 0: Check if n is a power of two
6 # - Powers of two have only one bit set
7 # - n & (n-1) clears the rightmost set bit
8 # - If result is 0, n had only one bit set
9 # 3. (n & 0xAAAAAAAA) == 0: Ensure the single bit is at an even position
10 # - 0xAAAAAAAA = 10101010101010101010101010101010 in binary
11 # - This masks all odd bit positions (0-indexed)
12 # - Powers of four have their single bit at positions 0, 2, 4, 6, etc.
13 # - If n AND this mask equals 0, the bit is at an even position
14 return n > 0 and (n & (n - 1)) == 0 and (n & 0xAAAAAAAA) == 0
15
1class Solution {
2 /**
3 * Determines if a given integer is a power of four.
4 *
5 * @param n The integer to check
6 * @return true if n is a power of four, false otherwise
7 */
8 public boolean isPowerOfFour(int n) {
9 // Check three conditions:
10 // 1. n must be positive (powers of 4 are always positive)
11 boolean isPositive = n > 0;
12
13 // 2. n must be a power of 2 (using bit manipulation trick)
14 // If n is a power of 2, then n & (n-1) equals 0
15 // Example: 16 (10000) & 15 (01111) = 0
16 boolean isPowerOfTwo = (n & (n - 1)) == 0;
17
18 // 3. The single bit must be in an even position (0-indexed)
19 // 0xAAAAAAAA in binary is 10101010101010101010101010101010
20 // This mask has 1s in all odd positions (1, 3, 5, 7, ...)
21 // Powers of 4 have their single bit in even positions (0, 2, 4, 6, ...)
22 // So n & 0xAAAAAAAA should be 0 for powers of 4
23 boolean isBitInEvenPosition = (n & 0xAAAAAAAA) == 0;
24
25 // All three conditions must be true
26 return isPositive && isPowerOfTwo && isBitInEvenPosition;
27 }
28}
29
1class Solution {
2public:
3 bool isPowerOfFour(int n) {
4 // Check three conditions:
5 // 1. n > 0: Power of 4 must be positive
6 // 2. (n & (n - 1)) == 0: Check if n is a power of 2
7 // - Powers of 2 have only one bit set in binary representation
8 // - Subtracting 1 flips all bits after the single set bit
9 // - AND operation results in 0 for powers of 2
10 // 3. (n & 0xAAAAAAAA) == 0: Ensure the single bit is at an even position
11 // - 0xAAAAAAAA = 10101010101010101010101010101010 in binary
12 // - This mask has bits set at odd positions (0-indexed)
13 // - Powers of 4 have their single bit at even positions (bit 0, 2, 4, 6...)
14 // - AND with this mask should be 0 for powers of 4
15 return n > 0 && (n & (n - 1)) == 0 && (n & 0xAAAAAAAA) == 0;
16 }
17};
18
1/**
2 * Determines if a given number is a power of four.
3 *
4 * @param n - The number to check
5 * @returns true if n is a power of four, false otherwise
6 */
7function isPowerOfFour(n: number): boolean {
8 // Check three conditions:
9 // 1. n > 0: Powers of four must be positive
10 // 2. (n & (n - 1)) === 0: This checks if n is a power of two
11 // - Powers of two have only one bit set in binary representation
12 // - When we subtract 1, all bits after that single bit become 1
13 // - ANDing them results in 0
14 // 3. (n & 0xAAAAAAAA) === 0: This filters out powers of two that aren't powers of four
15 // - 0xAAAAAAAA in binary is 10101010101010101010101010101010
16 // - Powers of four have their single bit at even positions (0, 2, 4, 6...)
17 // - This mask has 1s at all odd positions, so ANDing with powers of four gives 0
18 return n > 0 && (n & (n - 1)) === 0 && (n & 0xAAAAAAAA) === 0;
19}
20
Time and Space Complexity
The time complexity is O(1)
because the algorithm performs a fixed number of bitwise operations regardless of the input size. Specifically, it executes:
- One comparison operation (
n > 0
) - Two bitwise AND operations (
&
) - One subtraction operation (
n - 1
) - Two equality checks (
==
)
All these operations take constant time for integer values.
The space complexity is O(1)
because the algorithm uses only a constant amount of extra space. No additional data structures are created, and the space usage doesn't depend on the input value n
. The algorithm only uses the input parameter and performs in-place bitwise operations with constant values (0xAAAAAAAA
is a hexadecimal constant).
Common Pitfalls
1. Incorrect Mask for Different Integer Sizes
The mask 0xAAAAAAAA
assumes 32-bit integers. In systems with 64-bit integers or when dealing with very large numbers, this mask might not cover all necessary bit positions.
Problem Example:
# For a 64-bit system, 4^31 = 4611686018427387904 # Binary: 0100000000000000000000000000000000000000000000000000000000000000 # The bit is at position 62 (even), but 0xAAAAAAAA only covers first 32 bits n = 4**31 # This is a valid power of four # Using 0xAAAAAAAA might give incorrect results for large powers of four
Solution: Use a mask that covers all possible bit positions for your system:
def isPowerOfFour(self, n: int) -> bool:
# Use 0xAAAAAAAAAAAAAAAA for 64-bit systems
# Or use a more general approach
return n > 0 and (n & (n - 1)) == 0 and (n & 0xAAAAAAAAAAAAAAAA) == 0
2. Forgetting Edge Cases
Not handling special cases like n = 0
or negative numbers before applying bit operations.
Problem Example:
# Without checking n > 0 first
def isPowerOfFour(self, n: int) -> bool:
# This would incorrectly process n = 0 or n = -16
return (n & (n - 1)) == 0 and (n & 0xAAAAAAAA) == 0
# For n = 0: (0 & -1) == 0 is True, leading to wrong result
Solution: Always check for positive numbers first:
def isPowerOfFour(self, n: int) -> bool:
if n <= 0:
return False
return (n & (n - 1)) == 0 and (n & 0xAAAAAAAA) == 0
3. Misunderstanding the Mask Pattern
Using the wrong mask value or misunderstanding which positions should be masked.
Problem Example:
# Incorrect mask - using 0x55555555 instead of 0xAAAAAAAA
def isPowerOfFour(self, n: int) -> bool:
# 0x55555555 = 01010101010101010101010101010101 (bits at even positions)
# This would check the opposite condition!
return n > 0 and (n & (n - 1)) == 0 and (n & 0x55555555) == 0
Solution:
Remember that 0xAAAAAAAA
has 1s at ODD positions (1, 3, 5, ...), and we want the result to be 0:
def isPowerOfFour(self, n: int) -> bool:
# 0xAAAAAAAA = 10101010101010101010101010101010
# Powers of 4 have bits at EVEN positions (0, 2, 4, ...)
return n > 0 and (n & (n - 1)) == 0 and (n & 0xAAAAAAAA) == 0
4. Alternative Approach Using Modulo
While the bit manipulation is elegant, a simpler (though potentially less efficient) approach exists:
def isPowerOfFour(self, n: int) -> bool:
# Alternative: powers of 4 when divided by 3 always give remainder 1
# This works because 4 ≡ 1 (mod 3), so 4^x ≡ 1^x ≡ 1 (mod 3)
return n > 0 and (n & (n - 1)) == 0 and n % 3 == 1
This approach avoids the mask complexity but introduces a modulo operation.
Which of the following uses divide and conquer strategy?
Recommended Readings
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
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
Want a Structured Path to Master System Design Too? Don’t Miss This!