Given an integer x and an array arr[] each element of which is a power of 2. The task is to find the minimum number of integer powers of 2 from the array which when added give x. If it is not possible to represent x with the given array elements then print -1.
Examples:
Input: arr[] = {2, 4, 8, 2, 4}, x = 14
Output: 3
14 can be written as 8 + 4 + 2
Input: arr[] = {2, 4, 8, 2, 4}, x = 5
Output: -1
5 cannot be represented as the sum any elements from the given array.
Approach: For each power of 2 let’s calculate the number of elements in the given array with the value equals this. Let’s call it cnt. It is obvious that we can obtain the value x greedily (because all fewer values of elements are divisors of all greater values of elements).
Now let’s iterate over all powers of 2 from 30 to 0. Let’s deg be the current degree. We can take min(x / 2deg, cntdeg) elements with the value equals 2deg. Let it be cur. Add cur to the answer and subtract 2deg * cur from x. Repeat the process until the x can no longer be reduced. If after iterating over all powers, x is still non-zero then print -1. Otherwise, print the answer.
Below is the implementation of the above approach:
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std;
// Function to return the minimum number // of given integer powers of 2 required // to represent a number as sum of these powers int power_of_two( int n, int a[], int x)
{ // To store the count of powers of two
vector< int > cnt(31);
for ( int i = 0; i < n; ++i) {
// __builtin_ctz(a[i]) returns the count
// of trailing 0s in a[i]
++cnt[__builtin_ctz(a[i])];
}
int ans = 0;
for ( int i = 30; i >= 0 && x > 0; --i) {
// If current power is available
// in the array and can be used
int need = min(x >> i, cnt[i]);
// Update the answer
ans += need;
// Reduce the number
x -= (1 << i) * need;
}
// If the original number is not reduced to 0
// It cannot be represented as the sum
// of the given powers of 2
if (x > 0)
ans = -1;
return ans;
} // Driver code int main()
{ int arr[] = { 2, 2, 4, 4, 8 }, x = 6;
int n = sizeof (arr) / sizeof (arr[0]);
cout << power_of_two(n, arr, x);
return 0;
} |
// Java implementation of the approach import java.util.*;
class GFG
{ // __builtin_ctz(a[i]) returns the count // of trailing 0s in a[i] static int __builtin_ctz( int a)
{ int count = 0 ;
for ( int i = 0 ; i < 40 ; i++)
if (((a >> i) & 1 ) == 0 )
{
count++;
}
else
break ;
return count;
} // Function to return the minimum number // of given integer powers of 2 required // to represent a number as sum of these powers static int power_of_two( int n, int a[], int x)
{ // To store the count of powers of two
Vector<Integer> cnt = new Vector<Integer>();
for ( int i = 0 ; i < 31 ; ++i)
cnt.add( 0 );
for ( int i = 0 ; i < n; ++i)
{
// __builtin_ctz(a[i]) returns the count
// of trailing 0s in a[i]
cnt.set(__builtin_ctz(a[i]),
(cnt.get(__builtin_ctz(a[i]))== null ) ?
1 : cnt.get(__builtin_ctz(a[i]))+ 1 );
}
int ans = 0 ;
for ( int i = 30 ; i >= 0 && x > 0 ; --i)
{
// If current power is available
// in the array and can be used
int need = Math.min(x >> i, cnt.get(i));
// Update the answer
ans += need;
// Reduce the number
x -= ( 1 << i) * need;
}
// If the original number is not reduced to 0
// It cannot be represented as the sum
// of the given powers of 2
if (x > 0 )
ans = - 1 ;
return ans;
} // Driver code public static void main(String args[])
{ int arr[] = { 2 , 2 , 4 , 4 , 8 }, x = 6 ;
int n = arr.length;
System.out.println(power_of_two(n, arr, x));
} } // This code is contributed by Arnab Kundu |
# Python3 implementation of the approach # Function to return the minimum number # of given eger powers of 2 required # to represent a number as sum of these powers def power_of_two( n, a, x):
# To store the count of powers of two
cnt = [ 0 for i in range ( 31 )]
for i in range (n):
# __builtin_ctz(a[i]) returns the count
# of trailing 0s in a[i]
count = 0
xx = a[i]
while ((xx & 1 ) = = 0 ):
xx = xx >> 1
count + = 1
cnt[count] + = 1
ans = 0
for i in range ( 30 , - 1 , - 1 ):
if x< = 0 :
continue
# If current power is available
# in the array and can be used
need = min (x >> i, cnt[i])
# Update the answer
ans + = need
# Reduce the number
x - = ( 1 << i) * need
# If the original number is not reduced to 0
# It cannot be represented as the sum
# of the given powers of 2
if (x > 0 ):
ans = - 1
return ans
# Driver code arr = [ 2 , 2 , 4 , 4 , 8 ]
x = 6
n = len (arr)
print (power_of_two(n, arr, x))
# This code is contributed by mohit kumar 29 |
// C# implementation of the approach using System;
class GFG
{ // __builtin_ctz(a[i]) returns the count // of trailing 0s in a[i] static int __builtin_ctz( int a)
{ int count = 0;
for ( int i = 0; i < 40; i++)
if (((a >> i) & 1) == 0)
{
count++;
}
else
break ;
return count;
} // Function to return the minimum number // of given integer powers of 2 required // to represent a number as sum of these powers static int power_of_two( int n, int []a, int x)
{ // To store the count of powers of two
int [] cnt = new int [32];
for ( int i = 0; i < n; ++i)
{
// __builtin_ctz(a[i]) returns the count
// of trailing 0s in a[i]
cnt[__builtin_ctz(a[i])] =
cnt[__builtin_ctz(a[i])] ==
0?1 : cnt[__builtin_ctz(a[i])] + 1;
}
int ans = 0;
for ( int i = 30; i >= 0 && x > 0; --i)
{
// If current power is available
// in the array and can be used
int need = Math.Min(x >> i, cnt[i]);
// Update the answer
ans += need;
// Reduce the number
x -= (1 << i) * need;
}
// If the original number is not reduced to 0
// It cannot be represented as the sum
// of the given powers of 2
if (x > 0)
ans = -1;
return ans;
} // Driver code static void Main()
{ int []arr = { 2, 2, 4, 4, 8 };
int x = 6;
int n = arr.Length;
Console.WriteLine(power_of_two(n, arr, x));
} } // This code is contributed by mits |
<script> // JavaScript implementation of the approach // Function to return the minimum number // of given integer powers of 2 required // to represent a number as sum of these powers function power_of_two( n, a, x)
{ // To store the count of powers of two
let cnt = [];
for (let i = 0;i<31;i++)
cnt.push(0);
for (let i = 0; i < n; ++i) {
// __builtin_ctz(a[i]) returns the count
// of trailing 0s in a[i]
let count = 0;
let xx = a[i];
while ((xx & 1) == 0){
xx = xx >> 1
count += 1
}
cnt[count]+=1;
}
let ans = 0;
for (let i = 30; i >= 0 && x > 0; --i) {
// If current power is available
// in the array and can be used
let need = Math.min(x >> i, cnt[i]);
// Update the answer
ans += need;
// Reduce the number
x -= (1 << i) * need;
}
// If the original number is not reduced to 0
// It cannot be represented as the sum
// of the given powers of 2
if (x > 0)
ans = -1;
return ans;
} // Driver code let arr = [ 2, 2, 4, 4, 8 ], x = 6; let n = arr.length; document.write( power_of_two(n, arr, x)); </script> |
2
Time Complexity: O(N)
Auxiliary Space: O(32), since no extra space has been taken.
Another Approach(Space optimization):
We can Binary search to find the index such that a[index] <= x .and reduce x to x-a[index] and increase ans by 1. and until our x become 0. If there is not any index of array a[] at any time such that a[index] <= x .we simply assign ans=-1 and print ans.
Below is the implementation of the above approach:
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std;
//Function to find index such that a[index] <= x int binarysearch( int arr[], int N, int x)
{ int l = 0, r = N- 1, index = -1;
while (l <= r) {
int mid = (l + r) / 2;
// Checking if the middle element is less
// than or equal equal to x
if (arr[mid] <= x) {
index = mid ;
l = mid + 1;
}
else {
r = mid - 1;
}
}
// return -1 if there is no index such that a[index] <= x
//return that index such that a[index] <= x
return index;
} // Function to return the minimum number // of given integer powers of 2 required // to represent a number as sum of these powers int power_of_two( int n, int a[], int x)
{ int ans=0;
while (x!=0)
{ // Binary search to find index of array a
// such that a[index] <= x
int index = binarysearch(a , n, x);
if (index == -1)
{ // if there is no element in the array
// such that a[index] <= x
ans=-1; break ;
}
else {
//if there is a index of array a such that
// a[index] <= x ,then increase ans by 1
x =x- a[index]; ans++;
}
}
//return ans
return ans;
} // Driver code int main()
{ int arr[] = { 2, 2, 4, 4, 8 }, x = 6;
int n = sizeof (arr) / sizeof (arr[0]);
//Function call
cout << power_of_two(n, arr, x);
return 0;
} // This code is contributed by nikhilsainiofficial546 |
public class Main {
// Function to find index such that a[index] <= x
static int binarysearch( int [] arr, int N, int x) {
int l = 0 , r = N - 1 , index = - 1 ;
while (l <= r) {
int mid = (l + r) / 2 ;
// Checking if the middle element is less
// than or equal equal to x
if (arr[mid] <= x) {
index = mid;
l = mid + 1 ;
} else {
r = mid - 1 ;
}
}
// return -1 if there is no index such that a[index] <= x
// return that index such that a[index] <= x
return index;
}
// Function to return the minimum number
// of given integer powers of 2 required
// to represent a number as sum of these powers
static int power_of_two( int n, int [] a, int x) {
int ans = 0 ;
while (x != 0 ) {
// Binary search to find index of array a
// such that a[index] <= x
int index = binarysearch(a, n, x);
if (index == - 1 ) {
// if there is no element in the array
// such that a[index] <= x
ans = - 1 ;
break ;
} else {
// if there is a index of array a such that
// a[index] <= x ,then increase ans by 1
x -= a[index];
ans += 1 ;
}
}
// return ans
return ans;
}
// Driver code
public static void main(String[] args) {
int [] arr = { 2 , 2 , 4 , 4 , 8 };
int x = 6 ;
int n = arr.length;
// Function call
System.out.println(power_of_two(n, arr, x));
}
} |
# Function to find index such that a[index] <= x def binarysearch(arr, N, x):
l, r, index = 0 , N - 1 , - 1
while l < = r:
mid = (l + r) / / 2
# Checking if the middle element is less
# than or equal equal to x
if arr[mid] < = x:
index = mid
l = mid + 1
else :
r = mid - 1
# return -1 if there is no index such that a[index] <= x
#return that index such that a[index] <= x
return index
# Function to return the minimum number # of given integer powers of 2 required # to represent a number as sum of these powers def power_of_two(n, a, x):
ans = 0
while x ! = 0 :
# Binary search to find index of array a
# such that a[index] <= x
index = binarysearch(a, n, x)
if index = = - 1 :
# if there is no element in the array
# such that a[index] <= x
ans = - 1
break
else :
# if there is a index of array a such that
# a[index] <= x ,then increase ans by 1
x - = a[index]
ans + = 1
#return ans
return ans
# Driver code if __name__ = = '__main__' :
arr = [ 2 , 2 , 4 , 4 , 8 ]
x = 6
n = len (arr)
#Function call
print (power_of_two(n, arr, x))
|
using System;
class Gfg
{ // Function to find index such that a[index] <= x
static int binarysearch( int [] arr, int N, int x)
{
int l = 0, r = N - 1, index = -1;
while (l <= r)
{
int mid = (l + r) / 2;
// Checking if the middle element is less
// than or equal equal to x
if (arr[mid] <= x)
{
index = mid;
l = mid + 1;
}
else
{
r = mid - 1;
}
}
// return -1 if there is no index such that a[index] <= x
// return that index such that a[index] <= x
return index;
}
// Function to return the minimum number
// of given integer powers of 2 required
// to represent a number as sum of these powers
static int power_of_two( int n, int [] a, int x)
{
int ans = 0;
while (x != 0)
{
// Binary search to find index of array a
// such that a[index] <= x
int index = binarysearch(a, n, x);
if (index == -1)
{
// if there is no element in the array
// such that a[index] <= x
ans = -1; break ;
}
else
{
// if there is a index of array a such that
// a[index] <= x, then increase ans by 1
x -= a[index]; ans++;
}
}
// return ans
return ans;
}
static void Main( string [] args)
{
int [] arr = { 2, 2, 4, 4, 8 };
int x = 6;
int n = arr.Length;
// Function call
Console.WriteLine(power_of_two(n, arr, x));
}
} |
//javascript equivalent of the above code // Function to find index such that a[index] <= x function binarysearch(arr, N, x) {
let l = 0;
let r = N-1;
let index = -1;
while (l <= r) {
let mid = Math.trunc((l + r) / 2);
// Checking if the middle element is less
// than or equal equal to x
if (arr[mid] <= x) {
index = mid;
l = mid + 1;
}
else {
r = mid - 1;
}
}
// return -1 if there is no index such that a[index] <= x
//return that index such that a[index] <= x
return index;
} // Function to return the minimum number // of given integer powers of 2 required // to represent a number as sum of these powers function power_of_two(n, a, x) {
let ans = 0;
while (x != 0) {
// Binary search to find index of array a
// such that a[index] <= x
let index = binarysearch(a, n, x);
if (index == -1) {
// if there is no element in the array
// such that a[index] <= x
ans = -1;
break ;
}
else {
// if there is a index of array a such that
// a[index] <= x ,then increase ans by 1
x -= a[index];
ans += 1;
}
}
//return ans
return ans;
} // Driver code let arr = [2, 2, 4, 4, 8]; let x = 6; let n = arr.length; //Function call console.log(power_of_two(n, arr, x)); |
2
Time Complexity: O(x*logn) because binary search has a time complexity of O(logn)
Auxiliary Space: O(1)
Another Approach(Dynamic Programming.): We can define dp[i] as the minimum number of powers of 2 required to represent the number i.
Algorithm:
- Create an array dp of size x+1 to store the minimum number of powers of 2 required to represent each number from 0 to x.
- Initialize dp[0] to 0 since we don’t need any powers of 2 and to represent 0 and use a nested loop to iterate over each number i from 1 to x, and for each i, iterate over each power of 2 in the array arr and that is less than or equal to i.
- Calculate the minimum number of powers of 2 required to represent the difference i – arr[j], and add 1 to this to get the minimum number of powers of 2 required to represent i.
- Store this value in dp[i] and finally, return dp[x] if it is less than or equal to x and indicating that it is possible to represent x using the given array elements, otherwise return -1.
Below is the implementation of the above approach:
#include <bits/stdc++.h> using namespace std;
int min_powers_of_2( int arr[], int n, int x) {
int dp[x+1];
dp[0] = 0;
for ( int i = 1; i <= x; i++) {
dp[i] = INT_MAX;
for ( int j = 0; j < n; j++) {
if (arr[j] <= i) {
int sub_res = dp[i - arr[j]];
if (sub_res != INT_MAX) {
dp[i] = min(dp[i], sub_res + 1);
}
}
}
}
return dp[x] == INT_MAX ? -1 : dp[x];
} int main() {
int arr[] = {2, 2, 4, 4, 8};
int n = sizeof (arr) / sizeof (arr[0]);
int x = 6;
int result = min_powers_of_2(arr, n, x);
cout << result << endl;
return 0;
} |
public class Main {
public static int minPowersOf2( int [] arr, int n, int x)
{
// Create an array to store minimum powers of 2
// required to make each sum
int [] dp = new int [x + 1 ];
// Initialize the first element of the array as 0
// since we need 0 powers of 2 to make a sum of 0
dp[ 0 ] = 0 ;
// Iterate through all possible sums from 1 to x
for ( int i = 1 ; i <= x; i++) {
// Initialize the current sum's minimum powers
// of 2 requirement as maximum possible value
dp[i] = Integer.MAX_VALUE;
// Iterate through the array of available
// numbers
for ( int j = 0 ; j < n; j++) {
// Check if the current number can be used
// to make the current sum
if (arr[j] <= i) {
// Calculate the minimum powers of 2
// required to make the remaining sum
int subRes = dp[i - arr[j]];
// Check if a valid sub-result exists
// (i.e., the remaining sum is
// achievable)
if (subRes != Integer.MAX_VALUE) {
// Update the current sum's minimum
// powers of 2 requirement if the
// new option is better
dp[i] = Math.min(dp[i], subRes + 1 );
}
}
}
}
// Check if it's not possible to make the sum x with
// the available numbers
if (dp[x] == Integer.MAX_VALUE) {
return - 1 ;
}
else {
// Return the minimum powers of 2 required to
// make the sum x
return dp[x];
}
}
public static void main(String[] args)
{
int [] arr = { 2 , 2 , 4 , 4 , 8 };
int n = arr.length;
int x = 6 ;
// Calculate the minimum powers of 2 required to
// make sum x
int result = minPowersOf2(arr, n, x);
// Print the result to the console
System.out.println(result);
}
} |
import sys
def min_powers_of_2(arr, n, x):
dp = [sys.maxsize] * (x + 1 )
dp[ 0 ] = 0
for i in range ( 1 , x + 1 ):
for j in range (n):
if arr[j] < = i:
sub_res = dp[i - arr[j]]
if sub_res ! = sys.maxsize:
dp[i] = min (dp[i], sub_res + 1 )
return - 1 if dp[x] = = sys.maxsize else dp[x]
if __name__ = = '__main__' :
arr = [ 2 , 2 , 4 , 4 , 8 ]
n = len (arr)
x = 6
result = min_powers_of_2(arr, n, x)
print (result)
|
using System;
namespace MinPowersOf2Example
{ class Program
{
static int MinPowersOf2( int [] arr, int n, int x)
{
int [] dp = new int [x + 1];
dp[0] = 0;
for ( int i = 1; i <= x; i++)
{
dp[i] = int .MaxValue;
for ( int j = 0; j < n; j++)
{
if (arr[j] <= i)
{
int sub_res = dp[i - arr[j]];
if (sub_res != int .MaxValue)
{
dp[i] = Math.Min(dp[i], sub_res + 1);
}
}
}
}
return dp[x] == int .MaxValue ? -1 : dp[x];
}
static void Main( string [] args)
{
int [] arr = { 2, 2, 4, 4, 8 };
int n = arr.Length;
int x = 6;
int result = MinPowersOf2(arr, n, x);
Console.WriteLine(result);
}
}
} |
// Function to find the minimum number of powers of 2 needed to sum up to 'x' function minPowersOf2(arr, n, x) {
// Creating an array 'dp' to store minimum
// counts for each value from 0 to 'x'
const dp = Array(x + 1).fill(Number.MAX_SAFE_INTEGER);
// Base case: Minimum count to make 0 is 0
dp[0] = 0;
// Iterate over each value from 1 to 'x'
for (let i = 1; i <= x; i++) {
// Iterate over the elements in the array 'arr'
for (let j = 0; j < n; j++) {
// If the current element is less than or equal to 'i'
if (arr[j] <= i) {
// Calculate the sub-result based on the previous count (dp[i - arr[j]])
const subResult = dp[i - arr[j]];
// If sub-result is not the maximum value (indicating it's possible to reach i - arr[j])
if (subResult !== Number.MAX_SAFE_INTEGER) {
// Update dp[i] with the minimum count
dp[i] = Math.min(dp[i], subResult + 1);
}
}
}
}
// If dp[x] is still set to its initial maximum value, it means 'x' cannot be achieved
// Otherwise, dp[x] contains the minimum count to achieve 'x'
return dp[x] === Number.MAX_SAFE_INTEGER ? -1 : dp[x];
} // Main function function main() {
const arr = [2, 2, 4, 4, 8];
const n = arr.length;
const x = 6;
const result = minPowersOf2(arr, n, x);
console.log(result);
} // Calling the main function main(); // This code is contributed by Dwaipayan Bandyopadhyay |
2
Time Complexity: O(nx), where n is the size of the array and x is the given number to be represented. This is because we are iterating over each number from 1 to x, and for each number, we are iterating over each element in the array arr that is less than or equal to that number.
Auxiliary Space: O(x), because we are creating an array dp of size x+1 to store the minimum number of powers of 2 required to represent each number from 0 to x.