Check if a number can be represented as sum of non zero powers of 2 in Java

In this article, we go into the fascinating task of determining if a given integer, represented as N, can be stated as the sum of two separate non-zero powers of 2, following the formula (2^x + 2^y), where both x and y are positive integers. This approach imposes the constraint that the power of 2^0 cannot be included in the representation, emphasizing that both x and y must be bigger than 0.

Example:

Input: n=68

Output: 68 can be represented as the sum of non-zero powers of 2.

Explanation: For n = 68, It can be represented as 2^6+2^2.

Approach: Brute Force

The code determines whether the provided integer number is even by calculating whether it can be represented as the sum of non-zero powers of two.

FileName: PowerCheck.java

public class PowerCheck {

 public static boolean canBeRepresentedAsPowerOf2Sum(int n) {

        return n % 2 == 0;

    }

    public static void main(String[] args) {

        int n = 68;

        if (canBeRepresentedAsPowerOf2Sum(n)) {

            System.out.println(n + " can be represented as the sum of non-zero powers of 2.");

        } else {

            System.out.println(n + " cannot be represented as the sum of non-zero powers of 2.");

        }

    }

}

Output:

68 can be represented as the sum of non-zero powers of 2.

Complexity Analysis: The algorithm has a time complexity of O(1) because it only performs one arithmetic operation. The space complexity is also O(1), as no additional data structures are utilized.

Approach: Using Recursion

The PowerCheck class performs recursive backtracking to determine whether a positive integer n can be represented as the sum of non-zero powers of two. The method canBeRepresentedAsPowerOf2Sum() iterates over all potential powers and invokes the recursive helper function checkPowerOf2Sum() to investigate combinations by subtracting powers of 2. The basic case of checkPowerOf2Sum() returns true when n equals zero, indicating an acceptable combination, and false when n is negative or the current power exceeds the logarithm of n + 1 to base 2.


FileName: PowerCheck1.java

public class PowerCheck1 {

    public static boolean canBeRepresentedAsPowerOf2Sum(int n) {

        if (n <= 0) return false;

        // Try all combinations of non-zero powers of 2

        for (int i = 1; i < n; i++) {

            if (checkPowerOf2Sum(n, i)) return true;

        }

        return false;

    }

    private static boolean checkPowerOf2Sum(int n, int power) {

        if (n == 0) return true;

        // If n is negative or power exceeds the maximum power needed to represent n, return false

        if (n < 0 || power > Math.ceil(Math.log(n + 1) / Math.log(2))) return false;

        return checkPowerOf2Sum(n - (int) Math.pow(2, power), power + 1)

                || checkPowerOf2Sum(n, power + 1);

    }

    public static void main(String[] args) {

        int n = 68;

        if (canBeRepresentedAsPowerOf2Sum(n)) {

            System.out.println(n + " can be represented as the sum of non-zero powers of 2.");

        } else {

            System.out.println(n + " cannot be represented as the sum of non-zero powers of 2.");

        }

    }

}

Output:

68 can be represented as the sum of non-zero powers of 2.

Complexity Analysis: The code's time complexity is exponential, O(2^n), as it examines all conceivable combinations of non-zero powers of two. The space complexity is O(n), which denotes the maximum depth of the recursion stack.


Approach: Using Dynamic Programming

The PowerCheck class contains the canBeRepresentedAsPowerOf2Sum() function, which uses dynamic programming to determine if a given positive integer n can be represented as the sum of non-zero powers of 2. The procedure creates a boolean array dp of size n + 1, with dp[0] equal to true. It then iterates through powers of two, updating the array according to possible sums. The nested loop iterates through the array elements, checking each power of two to see if the current element can be constructed as the sum of those powers. The method returns true when n can be expressed and false otherwise.

FileName: PowerCheck2.java

import java.util.Arrays;

public class PowerCheck2 {

    public static boolean canBeRepresentedAsPowerOf2Sum(int n) {

        if (n <= 0) {

            return false;

        }

        int maxPower = (int) (Math.log(n + 1) / Math.log(2));

        boolean[] dp = new boolean[n + 1];

        dp[0] = true;

        for (int power = 1; power <= maxPower; power++) {

            for (int i = n; i >= Math.pow(2, power) && i >= 0; i--) {

                dp[i] = dp[i] || dp[i - (int) Math.pow(2, power)];

            }

        }

        return dp[n];

    }

    public static void main(String[] args) {

        int n = 68;

        if (canBeRepresentedAsPowerOf2Sum(n)) {

            System.out.println(n + " can be represented as the sum of non-zero powers of 2.");

        } else {

            System.out.println(n + " cannot be represented as the sum of non-zero powers of 2.");

        }

    }

}

Output:

68 can be represented as the sum of non-zero powers of 2

Complexity Analysis: The time complexity of the canBeRepresentedAsPowerOf2Sum() method is determined by the nested loop that iterates through array elements and the logarithmic factor linked to powers of two. As a result, the temporal complexity is roughly O(n*log(n)). The space complexity is O(n) since the boolean array dp stores intermediate results for each possible sum.