Minimum number of given powers of 2 required to represent a number
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++
// 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
// 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 |
python
# 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#
// 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 |
Javascript
<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.
Please Login to comment...