Count ways to represent N as sum of powers of 2
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++
#include <bits/stdc++.h>
using namespace std;
int numberOfWays( int n, int k)
{
if (n == 0)
return 1;
if (k == 0)
return 1;
if (n >= pow (2, k)) {
int curr_val = pow (2, k);
return numberOfWays(n - curr_val, k)
+ numberOfWays(n, k - 1);
}
else
return numberOfWays(n, k - 1);
}
int main()
{
int n = 4;
int k = log2(n);
cout << numberOfWays(n, k) << endl;
}
|
Java
import java.util.*;
class GFG
{
static int numberOfWays( int n, int k)
{
if (n == 0 )
return 1 ;
if (k == 0 )
return 1 ;
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 );
}
else
return numberOfWays(n, k - 1 );
}
public static void main(String[] args)
{
int n = 4 ;
int k = ( int )(Math.log(n) / Math.log( 2 ));
System.out.println(numberOfWays(n, k));
}
}
|
Python3
from math import log2
def numberOfWays(n, k):
if (n = = 0 ):
return 1
if (k = = 0 ):
return 1
if (n > = pow ( 2 , k)):
curr_val = pow ( 2 , k)
return numberOfWays(n - curr_val, k) + numberOfWays(n, k - 1 )
else :
return numberOfWays(n, k - 1 )
if __name__ = = '__main__' :
n = 4
k = log2(n)
print (numberOfWays(n, k))
|
C#
using System;
class GFG
{
static int numberOfWays( int n, int k)
{
if (n == 0)
return 1;
if (k == 0)
return 1;
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);
}
else
return numberOfWays(n, k - 1);
}
public static void Main(String[] args)
{
int n = 4;
int k = ( int )(Math.Log(n) / Math.Log(2));
Console.WriteLine(numberOfWays(n, k));
}
}
|
Javascript
<script>
function numberOfWays(n, k)
{
if (n == 0)
return 1;
if (k == 0)
return 1;
if (n >= Math.pow(2, k)) {
let curr_val = Math.pow(2, k);
return numberOfWays(n - curr_val, k)
+ numberOfWays(n, k - 1);
}
else
return numberOfWays(n, k - 1);
}
let n = 4;
let k = Math.log2(n);
document.write(numberOfWays(n, k) + "<br>" );
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
int numberOfWays( int n)
{
int dp[n+1] = {0};
dp[0] = 1;
for ( int i = 1; i <= n; i = i*2)
{
for ( int j = i; j <= n; j++)
{
dp[j] += dp[j-i];
}
}
return dp[n];
}
int main() {
int n=4;
cout << "Number of ways: " << numberOfWays(n) << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
static int numberOfWays( int n)
{
int dp[] = new int [n + 1 ];
dp[ 0 ] = 1 ;
for ( int i = 1 ; i <= n; i = i * 2 ) {
for ( int j = i; j <= n; j++) {
dp[j] += dp[j - i];
}
}
return dp[n];
}
public static void main(String[] args)
{
int n = 4 ;
System.out.println( "Number of ways: "
+ numberOfWays(n));
}
}
|
Python3
def numberOfWays(n):
dp = [ 0 for i in range (n + 1 )]
dp[ 0 ] = 1
i = 1
while i < = n:
j = i
while j < = n:
dp[j] + = dp[j - i]
j + = 1
i * = 2
return dp[n]
if __name__ = = '__main__' :
n = 4
print ( "Number of ways:" , numberOfWays(n))
|
C#
using System;
public class GFG
{
static int NumberOfWays( int n)
{
int [] dp = new int [n + 1];
dp[0] = 1;
for ( int i = 1; i <= n; i = i * 2)
{
for ( int j = i; j <= n; j++)
{
dp[j] += dp[j - i];
}
}
return dp[n];
}
public static void Main( string [] args)
{
int n = 4;
Console.WriteLine( "Number of ways: " + NumberOfWays(n));
}
}
|
Javascript
function numberOfWays(n) {
let dp = new Array(n+1).fill(0);
dp[0] = 1;
let i = 1;
while (i <= n) {
let j = i;
while (j <= n) {
dp[j] += dp[j-i];
j += 1;
}
i *= 2;
}
return dp[n];
}
let n = 4;
console.log( "Number of ways:" , numberOfWays(n));
|
Time Complexity: O(N*logN), logN time to iterate all powers of 2 that is <=N
Auxiliary Space: O(N)
Last Updated :
14 Mar, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...