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 |
4
Time Complexity: O((logN+K)K ), where K is log2(N)
Auxiliary Space: O(1)
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.