Bird
Raised Fist0
Interview Prepbit-manipulationeasyAmazonGoogle

Power of Four

Choose your preparation mode4 modes available
🎯
Power of Four
easyBIT_MANIPULATIONAmazonGoogle

Imagine you are designing a system that needs to quickly verify if a given number represents a perfect power of four, which is crucial for optimizing memory alignment in hardware.

💡 This problem tests understanding of bit manipulation and number properties. Beginners often struggle because they try to use loops or math functions instead of leveraging binary patterns that uniquely identify powers of four.
📋
Problem Statement

Given an integer n, determine if it is a power of four. Return true if it is, otherwise return false. Input: integer n. Output: boolean indicating if n is a power of four.

-2^31 <= n <= 2^31 - 1You must solve it without using loops or recursion.
💡
Example
Input"16"
Outputtrue

16 is 4^2, so it is a power of four.

Input"5"
Outputfalse

5 is not a power of four.

  • 0 → false (zero is not a power of four)
  • 1 → true (4^0 = 1)
  • -4 → false (negative numbers cannot be powers of four)
  • Integer max value (2^31 - 1) → false (not a power of four)
⚠️
Common Mistakes
Checking only if n is a power of two

Returns true for powers of two that are not powers of four, e.g., 8

✅ Add mask check to ensure the set bit is at an even position

Using floating point equality for log checks without tolerance

Fails for some inputs due to floating point precision errors

✅ Avoid floating point checks or use bit manipulation instead

Not handling zero and negative inputs

Incorrectly returns true or causes errors

✅ Explicitly check and return false for n <= 0

Using loops or recursion when problem states no loops

Fails interview requirement or inefficient solution

✅ Use bit manipulation for constant time solution

🧠
Brute Force (Iterative Division)
💡 This approach exists to build intuition by directly checking the definition of power of four through repeated division, which is straightforward but inefficient.

Intuition

Repeatedly divide the number by 4 if it is divisible until it becomes 1. If at any point it is not divisible by 4, return false.

Algorithm

  1. If n is less than or equal to 0, return false.
  2. While n is greater than 1, check if n is divisible by 4.
  3. If not divisible, return false.
  4. Divide n by 4 and continue.
  5. If loop ends with n equal to 1, return true.
💡 This algorithm directly follows the mathematical definition but can be slow for large inputs.
</>
Code
def isPowerOfFour(n: int) -> bool:
    if n <= 0:
        return False
    while n != 1:
        if n % 4 != 0:
            return False
        n //= 4
    return True

# Driver code
if __name__ == '__main__':
    test_cases = [16, 5, 1, 0, -4]
    for tc in test_cases:
        print(f'isPowerOfFour({tc}) = {isPowerOfFour(tc)}')
Line Notes
if n <= 0:Negative numbers and zero cannot be powers of four
while n != 1:Loop until we reduce n to 1 if it is a power of four
if n % 4 != 0:If n is not divisible by 4, it can't be a power of four
n //= 4Divide n by 4 to peel off one power layer
public class PowerOfFour {
    public static boolean isPowerOfFour(int n) {
        if (n <= 0) return false;
        while (n != 1) {
            if (n % 4 != 0) return false;
            n /= 4;
        }
        return true;
    }

    public static void main(String[] args) {
        int[] testCases = {16, 5, 1, 0, -4};
        for (int tc : testCases) {
            System.out.println("isPowerOfFour(" + tc + ") = " + isPowerOfFour(tc));
        }
    }
}
Line Notes
if (n <= 0) return false;Exclude zero and negative numbers early
while (n != 1)Keep dividing until n becomes 1
if (n % 4 != 0) return false;Check divisibility by 4 at each step
n /= 4;Reduce n by dividing by 4
#include <iostream>
using namespace std;

bool isPowerOfFour(int n) {
    if (n <= 0) return false;
    while (n != 1) {
        if (n % 4 != 0) return false;
        n /= 4;
    }
    return true;
}

int main() {
    int testCases[] = {16, 5, 1, 0, -4};
    for (int tc : testCases) {
        cout << "isPowerOfFour(" << tc << ") = " << (isPowerOfFour(tc) ? "true" : "false") << endl;
    }
    return 0;
}
Line Notes
if (n <= 0) return false;Filter out invalid inputs early
while (n != 1)Loop until n is reduced to 1
if (n % 4 != 0) return false;Check if n is divisible by 4
n /= 4;Divide n by 4 to check next power
function isPowerOfFour(n) {
    if (n <= 0) return false;
    while (n !== 1) {
        if (n % 4 !== 0) return false;
        n = n / 4;
    }
    return true;
}

// Test cases
[16, 5, 1, 0, -4].forEach(tc => {
    console.log(`isPowerOfFour(${tc}) = ${isPowerOfFour(tc)}`);
});
Line Notes
if (n <= 0) return false;Exclude zero and negative numbers immediately
while (n !== 1)Keep dividing until n becomes 1
if (n % 4 !== 0) return false;If not divisible by 4, return false
n = n / 4;Divide n by 4 to check next power
⏱
Complexity
TimeO(log n)
SpaceO(1)

Each division reduces n by a factor of 4, so the loop runs about log4(n) times, which is O(log n).

💡 For n=16, this means about 2 divisions; for n=1,000,000, about 10 divisions.
Interview Verdict: Accepted

This approach works but is not the most efficient or elegant for bit manipulation problems.

🧠
Bit Manipulation Using Power of Two Check and Bitmask
💡 This approach leverages the binary properties of powers of four, combining a power of two check with a mask to ensure the single set bit is in the correct position.

Intuition

A power of four is a power of two with its single set bit at an even position (0-based). First check if n is a power of two, then check if the set bit is in an even position using a mask.

Algorithm

  1. Check if n is positive and n & (n-1) == 0 to confirm power of two.
  2. Use mask 0x55555555 to check if the set bit is at an even position.
  3. Return true if both conditions hold, else false.
💡 This approach is efficient and uses constant time bitwise operations.
</>
Code
def isPowerOfFour(n: int) -> bool:
    if n <= 0:
        return False
    if (n & (n - 1)) != 0:
        return False
    if (n & 0x55555555) == 0:
        return False
    return True

# Driver code
if __name__ == '__main__':
    test_cases = [16, 5, 1, 0, -4]
    for tc in test_cases:
        print(f'isPowerOfFour({tc}) = {isPowerOfFour(tc)}')
Line Notes
if n <= 0:Exclude zero and negative numbers early
if (n & (n - 1)) != 0:Check if n is a power of two by verifying only one bit is set
if (n & 0x55555555) == 0:Check if the set bit is in an even position using mask
return TrueReturn true only if both conditions are met
public class PowerOfFour {
    public static boolean isPowerOfFour(int n) {
        if (n <= 0) return false;
        if ((n & (n - 1)) != 0) return false;
        if ((n & 0x55555555) == 0) return false;
        return true;
    }

    public static void main(String[] args) {
        int[] testCases = {16, 5, 1, 0, -4};
        for (int tc : testCases) {
            System.out.println("isPowerOfFour(" + tc + ") = " + isPowerOfFour(tc));
        }
    }
}
Line Notes
if (n <= 0) return false;Filter out invalid inputs
if ((n & (n - 1)) != 0) return false;Check single set bit for power of two
if ((n & 0x55555555) == 0) return false;Mask to ensure set bit is at even position
return true;Return true if all conditions satisfied
#include <iostream>
using namespace std;

bool isPowerOfFour(int n) {
    if (n <= 0) return false;
    if ((n & (n - 1)) != 0) return false;
    if ((n & 0x55555555) == 0) return false;
    return true;
}

int main() {
    int testCases[] = {16, 5, 1, 0, -4};
    for (int tc : testCases) {
        cout << "isPowerOfFour(" << tc << ") = " << (isPowerOfFour(tc) ? "true" : "false") << endl;
    }
    return 0;
}
Line Notes
if (n <= 0) return false;Exclude zero and negatives
if ((n & (n - 1)) != 0) return false;Check if n is power of two
if ((n & 0x55555555) == 0) return false;Mask to verify bit position
return true;Return true if all checks pass
function isPowerOfFour(n) {
    if (n <= 0) return false;
    if ((n & (n - 1)) !== 0) return false;
    if ((n & 0x55555555) === 0) return false;
    return true;
}

// Test cases
[16, 5, 1, 0, -4].forEach(tc => {
    console.log(`isPowerOfFour(${tc}) = ${isPowerOfFour(tc)}`);
});
Line Notes
if (n <= 0) return false;Exclude invalid inputs
if ((n & (n - 1)) !== 0) return false;Check single set bit for power of two
if ((n & 0x55555555) === 0) return false;Mask to ensure set bit is at even position
return true;Return true if all conditions met
⏱
Complexity
TimeO(1)
SpaceO(1)

All operations are constant time bitwise operations, independent of input size.

💡 This means the function runs instantly even for very large numbers.
Interview Verdict: Accepted

This is the optimal and most elegant solution for this problem.

🧠
Using Logarithm and Math Checks
💡 This approach uses mathematical properties and logarithms to check if the number is a power of four, which is intuitive but less efficient and can suffer from floating point precision issues.

Intuition

If n is a power of four, then log base 4 of n is an integer. We can compute log base 4 using log base 2 and check if the result is an integer.

Algorithm

  1. If n is less than or equal to 0, return false.
  2. Calculate log base 4 of n using log2(n) / log2(4).
  3. Check if the result is an integer by comparing with its rounded value.
  4. Return true if integer, else false.
💡 This approach is straightforward but can fail due to floating point precision errors.
</>
Code
import math

def isPowerOfFour(n: int) -> bool:
    if n <= 0:
        return False
    log_val = math.log2(n) / 2
    return log_val == int(log_val)

# Driver code
if __name__ == '__main__':
    test_cases = [16, 5, 1, 0, -4]
    for tc in test_cases:
        print(f'isPowerOfFour({tc}) = {isPowerOfFour(tc)}')
Line Notes
if n <= 0:Exclude invalid inputs
log_val = math.log2(n) / 2Calculate log base 4 by dividing log base 2 by 2
return log_val == int(log_val)Check if log_val is an integer
import mathImport math module for logarithm functions
public class PowerOfFour {
    public static boolean isPowerOfFour(int n) {
        if (n <= 0) return false;
        double logVal = Math.log(n) / Math.log(4);
        return logVal == (int)logVal;
    }

    public static void main(String[] args) {
        int[] testCases = {16, 5, 1, 0, -4};
        for (int tc : testCases) {
            System.out.println("isPowerOfFour(" + tc + ") = " + isPowerOfFour(tc));
        }
    }
}
Line Notes
if (n <= 0) return false;Filter invalid inputs
double logVal = Math.log(n) / Math.log(4);Calculate log base 4 using natural logs
return logVal == (int)logVal;Check if logVal is an integer
import java.lang.Math;Math class provides logarithm functions
#include <iostream>
#include <cmath>
using namespace std;

bool isPowerOfFour(int n) {
    if (n <= 0) return false;
    double logVal = log(n) / log(4);
    return logVal == (int)logVal;
}

int main() {
    int testCases[] = {16, 5, 1, 0, -4};
    for (int tc : testCases) {
        cout << "isPowerOfFour(" << tc << ") = " << (isPowerOfFour(tc) ? "true" : "false") << endl;
    }
    return 0;
}
Line Notes
if (n <= 0) return false;Exclude invalid inputs
double logVal = log(n) / log(4);Calculate log base 4 using natural logs
return logVal == (int)logVal;Check if logVal is an integer
#include <cmath>Include cmath for log functions
function isPowerOfFour(n) {
    if (n <= 0) return false;
    const logVal = Math.log(n) / Math.log(4);
    return logVal === Math.floor(logVal);
}

// Test cases
[16, 5, 1, 0, -4].forEach(tc => {
    console.log(`isPowerOfFour(${tc}) = ${isPowerOfFour(tc)}`);
});
Line Notes
if (n <= 0) return false;Exclude invalid inputs
const logVal = Math.log(n) / Math.log(4);Calculate log base 4 using natural logs
return logVal === Math.floor(logVal);Check if logVal is an integer
Math.logMath library provides logarithm functions
⏱
Complexity
TimeO(1)
SpaceO(1)

Logarithm calculations are constant time operations.

💡 This approach is fast but can be unreliable due to floating point precision.
Interview Verdict: Accepted (but less reliable)

While this approach works, it is not recommended in interviews due to precision issues and lack of bit manipulation practice.

📊
All Approaches - One-Glance Tradeoffs
💡 The bit manipulation approach is the best to code in interviews due to its efficiency and clarity.
ApproachTimeSpaceStack RiskReconstructUse In Interview
1. Brute Force (Iterative Division)O(log n)O(1)NoN/AMention only - never code
2. Bit Manipulation Using Power of Two Check and BitmaskO(1)O(1)NoN/ACode this approach
3. Using Logarithm and Math ChecksO(1)O(1)NoN/AMention as alternative, but not recommended
💼
Interview Strategy
💡 Use this guide to understand the problem deeply before interviews. Start with brute force to build intuition, then move to bit manipulation for optimal solutions.

How to Present

Step 1: Clarify the problem and constraints.Step 2: Present the brute force approach using division.Step 3: Explain the bit manipulation approach with power of two check and mask.Step 4: Optionally mention the logarithm approach and its drawbacks.Step 5: Code the optimal bit manipulation solution.Step 6: Test with edge cases and explain results.

Time Allocation

Clarify: 2min → Approach: 3min → Code: 5min → Test: 3min. Total ~13min

What the Interviewer Tests

Interviewer tests understanding of bitwise operations, number properties, and ability to optimize from brute force to constant time solutions.

Common Follow-ups

  • What if the input is a 64-bit integer? → Use 64-bit masks accordingly.
  • Can you do it without loops or recursion? → Yes, using bit manipulation.
💡 Follow-ups often test scalability and deeper bit manipulation knowledge.
🔍
Pattern Recognition

When to Use

1) Input is a single integer; 2) Need to check if it is a power of a number; 3) Constraints suggest bitwise operations; 4) Problem hints at masks or bit positions.

Signature Phrases

power of foursingle set bitbit mask 0xAAAAAAAAeven bit position

NOT This Pattern When

Problems asking for counting bits or toggling bits without power checks

Similar Problems

Power of Two - simpler version checking single set bitPower of Three - uses logarithms instead of bit manipulation

Practice

(1/5)
1. You need to compute the number of set bits (1s) in the binary representation of every integer from 0 up to a given number N efficiently. Which approach guarantees the optimal time complexity for this problem?
easy
A. Use Brian Kernighan's bit counting trick to count set bits for each number by repeatedly clearing the least significant set bit.
B. Use a dynamic programming approach that counts bits by building results from smaller subproblems using right shifts.
C. Use a greedy approach that counts bits by checking each bit position independently for all numbers.
D. Convert each number to a binary string and count the '1' characters using built-in string functions.

Solution

  1. Step 1: Understand the problem requirements

    The problem requires counting set bits for all numbers from 0 to N efficiently.
  2. Step 2: Evaluate approaches for optimality

    Brian Kernighan's trick counts set bits per number in O(k) time, where k is the number of set bits, but doing this for all numbers results in O(n log n) in worst case. The dynamic programming approach uses previously computed results and right shifts to achieve O(n) time complexity, which is optimal.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    DP approach is optimal for counting bits from 0 to N [OK]
Hint: DP approach builds on smaller subproblems for O(n) time [OK]
Common Mistakes:
  • Assuming Brian Kernighan's trick is optimal for all numbers
  • Using string conversion for speed
  • Greedy bit checking is optimal
2. You need to generate all permutations of n distinct elements efficiently. Which approach best balances time and space by using a compact representation of visited elements and avoids redundant recomputation?
easy
A. Backtracking with a boolean visited array and recursion without memoization
B. Greedy algorithm that picks the next smallest unused element at each step
C. Bitmask DP with iterative tabulation that uses bitmasks to track visited elements and builds permutations bottom-up
D. Dynamic programming on subsets without bitmasking, using nested loops over all permutations

Solution

  1. Step 1: Understand the problem constraints

    Generating all permutations requires enumerating all orderings of n elements, which is factorial in size. Efficient tracking of visited elements is crucial.
  2. Step 2: Identify the approach that uses bitmasking

    Bitmask DP uses an integer to represent visited elements compactly, enabling memoization and iterative building of permutations without redundant recomputation.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Bitmask DP with iterative tabulation is the known optimal approach for this problem [OK]
Hint: Bitmask DP uses bits to track visited elements efficiently [OK]
Common Mistakes:
  • Assuming greedy can generate all permutations correctly
  • Using DP without bitmasking leads to inefficient state tracking
3. Given the following Python code implementing sum of two integers without using + operator, what is the output when calling getSum(1, 2)?
easy
A. 2
B. 3
C. 1
D. 0

Solution

  1. Step 1: First call getSum(1, 2)

    sum_ = (1 ^ 2) & MASK = 3, carry = ((1 & 2) << 1) & MASK = 0
  2. Step 2: Since carry is 0, return sum_ = 3

    Base case reached, final sum is 3.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    1 + 2 = 3 matches output [OK]
Hint: XOR sum with carry zero returns final sum [OK]
Common Mistakes:
  • Confusing carry calculation
  • Off-by-one in recursion
  • Returning carry instead of sum
4. The following code attempts to find the single number in an array using XOR. Identify the line containing the subtle bug that causes incorrect results.
medium
A. Line 2: Initializing result to nums[0] instead of 0
B. Line 4: Returning result without sorting
C. Line 3: Looping over nums including the first element again
D. Line 1: Function definition

Solution

  1. Step 1: Analyze initialization of result

    Result initialized to nums[0], then XORed again with nums[0] in loop, cancelling it out incorrectly.
  2. Step 2: Understand correct initialization

    Result should start at 0 so XOR accumulates all elements exactly once.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Initializing to zero avoids double XOR of first element [OK]
Hint: XOR accumulator must start at zero [OK]
Common Mistakes:
  • Initializing with first element causes double XOR
  • Loop includes first element again
  • Misplaced return statement
5. Suppose the problem changes: you want to find the maximum product of word lengths where words can be reused multiple times (i.e., pairs can be the same word twice if allowed). Which modification to the optimal bitmasking approach correctly handles this variant?
hard
A. Precompute bitmasks and lengths, then for each word, consider its square length if it has no repeated characters, else zero; finally, check pairs as before including identical indices.
B. Remove the pruning condition and check all pairs including identical indices without overlap check.
C. Allow i and j to be equal in the nested loops and check bitmask overlap as before.
D. Use a frequency map of words and multiply lengths by frequency to find maximum product.

Solution

  1. Step 1: Understand reuse of words

    Reusing the same word twice is only valid if the word has no repeated characters (so no overlap with itself).
  2. Step 2: Modify approach

    Precompute bitmasks and lengths; for each word, consider its length squared if it has unique characters (bitmask check for duplicates). Then check pairs including identical indices.
  3. Step 3: Why other options fail

    Allowing i=j without checking duplicates or removing pruning leads to incorrect or inefficient results; frequency map is irrelevant here.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Considering squares for unique words and pairs covers reuse correctly [OK]
Hint: Reuse allowed only if word has unique chars [OK]
Common Mistakes:
  • Allowing reuse without checking duplicates in word
  • Removing pruning causing inefficiency
  • Using frequency maps which don't apply here
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard