Given an integer N, the task is to count the number of ways to represent N as the sum of powers of 2.
Examples:
Input: N = 4
Output: 4
Explanation: All possible ways to obtains sum N using powers of 2 are {4, 2+2, 1+1+1+1, 2+1+1}.Input: N = 5
Output: 4
Explanation: All possible ways to obtains sum N using powers of 2 are {4 + 1, 2+2 + 1, 1+1+1+1 + 1, 2+1+1 + 1}
Naive Approach: The simplest approach to solve the problem is to generate all powers of 2 whose values are less than N and print all combinations to represent the sum N.
Efficient Approach: To optimize the above approach, the idea is to use recursion. Define a function f(N, K) which represents the number of ways to express N as a sum of powers of 2 with all the numbers having power less than or equal to k where K ( = log2(N)) is the maximum power of 2 which satisfies 2K ? N.
If (power(2, K) ? N) :
f(N, K) = f(N – power(2, K), K) + f(N, K – 1) //to check if power(2, k) can be one of the number.
Otherwise:
f(N, K)=f(N, K – 1)
Base cases :
- If (N = 0) f(N, K)=1 (Only 1 possible way exists to represent N)
- If (k==0) f(N, K)=1 (Only 1 possible way exists to represent N by taking 20)
Below is the implementation of the above approach:
C++
// C++ program for above implementation #include <bits/stdc++.h> using namespace std; int numberOfWays( int n, int k) { // Base Cases if (n == 0) return 1; if (k == 0) return 1; // Check if 2^k can be used as // one of the numbers or not if (n >= pow (2, k)) { int curr_val = pow (2, k); return numberOfWays(n - curr_val, k) + numberOfWays(n, k - 1); } // Otherwise else // Count number of ways to // N using 2 ^ k - 1 return numberOfWays(n, k - 1); } // Driver Code int main() { int n = 4; int k = log2(n); cout << numberOfWays(n, k) << endl; } |
Java
// Java program to implement // the above approach import java.util.*; class GFG { static int numberOfWays( int n, int k) { // Base Cases if (n == 0 ) return 1 ; if (k == 0 ) return 1 ; // Check if 2^k can be used as // one of the numbers or not if (n >= ( int )Math.pow( 2 , k)) { int curr_val = ( int )Math.pow( 2 , k); return numberOfWays(n - curr_val, k) + numberOfWays(n, k - 1 ); } // Otherwise else // Count number of ways to // N using 2 ^ k - 1 return numberOfWays(n, k - 1 ); } // Driver code public static void main(String[] args) { int n = 4 ; int k = ( int )(Math.log(n) / Math.log( 2 )); System.out.println(numberOfWays(n, k)); } } // This code is contributed by susmitakundugoaldanga. |
Python3
# Python3 program for above implementation from math import log2 def numberOfWays(n, k): # Base Cases if (n = = 0 ): return 1 if (k = = 0 ): return 1 # Check if 2^k can be used as # one of the numbers or not if (n > = pow ( 2 , k)): curr_val = pow ( 2 , k) return numberOfWays(n - curr_val, k) + numberOfWays(n, k - 1 ) # Otherwise else : # Count number of ways to # N using 2 ^ k - 1 return numberOfWays(n, k - 1 ) # Driver Code if __name__ = = '__main__' : n = 4 k = log2(n) print (numberOfWays(n, k)) # This code is contributed by mohit kumar 29 |
C#
// C# program to implement // the above approach using System; class GFG { static int numberOfWays( int n, int k) { // Base Cases if (n == 0) return 1; if (k == 0) return 1; // Check if 2^k can be used as // one of the numbers or not if (n >= ( int )Math.Pow(2, k)) { int curr_val = ( int )Math.Pow(2, k); return numberOfWays(n - curr_val, k) + numberOfWays(n, k - 1); } // Otherwise else // Count number of ways to // N using 2 ^ k - 1 return numberOfWays(n, k - 1); } // Driver code public static void Main(String[] args) { int n = 4; int k = ( int )(Math.Log(n) / Math.Log(2)); Console.WriteLine(numberOfWays(n, k)); } } // This code is contributed by 29AjayKumar |
Javascript
<script> // JavaScript program for above implementation function numberOfWays(n, k) { // Base Cases if (n == 0) return 1; if (k == 0) return 1; // Check if 2^k can be used as // one of the numbers or not if (n >= Math.pow(2, k)) { let curr_val = Math.pow(2, k); return numberOfWays(n - curr_val, k) + numberOfWays(n, k - 1); } // Otherwise else // Count number of ways to // N using 2 ^ k - 1 return numberOfWays(n, k - 1); } // Driver Code let n = 4; let k = Math.log2(n); document.write(numberOfWays(n, k) + "<br>" ); // This code is contributed by Mayank Tyagi </script> |
4
Time Complexity: O((logN+K)K ), where K is log2(N)
Auxiliary Space: O(1)
Another Efficient Approach ( using DP) : First we iterate all values of power of 2<= N , starting from 1. Then , we will find value of big problem using value of small sub-problems .
Below is the implementation of the above approach:
C++
// C++ program for above implementation #include <bits/stdc++.h> using namespace std; // Function to count the number of ways to represent // n as the power of 2 int numberOfWays( int n) { // Initialize an array dp with size n+1 int dp[n+1] = {0}; // Base case- there is only 1 way to represent 0 // as a sum of powers of 2 dp[0] = 1; // Iterate all powers of 2 starting from 1 for ( int i = 1; i <= n; i = i*2) { // Iterate through all numbers from 1 to n for ( int j = i; j <= n; j++) { // Using sub-problems that is already calculated to find the // number of ways to represent j as a sum of powers of 2 dp[j] += dp[j-i]; } } // Return the number of ways to represent // n as a sum of powers of 2 return dp[n]; } //Drive code int main() { int n=4; //Function call cout << "Number of ways: " << numberOfWays(n) << endl; return 0; } // This code is contributed by nikhilsainiofficial546 |
Java
// Java program for above implementation import java.util.*; public class Main { // Function to count the number of ways to represent // n as the power of 2 static int numberOfWays( int n) { // Initialize an array dp with size n+1 int dp[] = new int [n + 1 ]; // Base case- there is only 1 way to represent 0 // as a sum of powers of 2 dp[ 0 ] = 1 ; // Iterate all powers of 2 starting from 1 for ( int i = 1 ; i <= n; i = i * 2 ) { // Iterate through all numbers from 1 to n for ( int j = i; j <= n; j++) { // Using sub-problems that is already // calculated to find the number of ways to // represent j as a sum of powers of 2 dp[j] += dp[j - i]; } } // Return the number of ways to represent // n as a sum of powers of 2 return dp[n]; } // Drive code public static void main(String[] args) { int n = 4 ; // Function call System.out.println( "Number of ways: " + numberOfWays(n)); } } |
Python3
# Python3 program for above implementation # Function to count the number of ways to represent # n as the power of 2 def numberOfWays(n): # Initialize an array dp with size n+1 dp = [ 0 for i in range (n + 1 )] # Base case- there is only 1 way to represent 0 # as a sum of powers of 2 dp[ 0 ] = 1 # Iterate all powers of 2 starting from 1 i = 1 while i < = n: # Iterate through all numbers from 1 to n j = i while j < = n: # Using sub-problems that is already calculated to find the # number of ways to represent j as a sum of powers of 2 dp[j] + = dp[j - i] j + = 1 i * = 2 # Return the number of ways to represent # n as a sum of powers of 2 return dp[n] # Drive code if __name__ = = '__main__' : n = 4 # Function call print ( "Number of ways:" , numberOfWays(n)) # This code is contributed by nikhilsainiofficial546 |
C#
// C# program for the above approach using System; public class GFG { // Function to count the number of ways to represent // n as the power of 2 static int NumberOfWays( int n) { // Initialize an array dp with size n+1 int [] dp = new int [n + 1]; // Base case- there is only 1 way to represent 0 // as a sum of powers of 2 dp[0] = 1; // Iterate all powers of 2 starting from 1 for ( int i = 1; i <= n; i = i * 2) { // Iterate through all numbers from 1 to n for ( int j = i; j <= n; j++) { // Using sub-problems that is already // calculated to find the number of ways to // represent j as a sum of powers of 2 dp[j] += dp[j - i]; } } // Return the number of ways to represent // n as a sum of powers of 2 return dp[n]; } // Drive code public static void Main( string [] args) { int n = 4; // Function call Console.WriteLine( "Number of ways: " + NumberOfWays(n)); } } // This code is contributed by sdeadityasharma |
Javascript
// Function to count the number of ways to represent // n as the power of 2 function numberOfWays(n) { // Initialize an array dp with size n+1 let dp = new Array(n+1).fill(0); // Base case- there is only 1 way to represent 0 // as a sum of powers of 2 dp[0] = 1; // Iterate all powers of 2 starting from 1 let i = 1; while (i <= n) { // Iterate through all numbers from 1 to n let j = i; while (j <= n) { // Using sub-problems that is already calculated to find the // number of ways to represent j as a sum of powers of 2 dp[j] += dp[j-i]; j += 1; } i *= 2; } // Return the number of ways to represent // n as a sum of powers of 2 return dp[n]; } // Driver code let n = 4; // Function call console.log( "Number of ways:" , numberOfWays(n)); |
Number of ways: 4
Time Complexity: O(N*logN), logN time to iterate all powers of 2 that is <=N
Auxiliary Space: O(N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!