Given an array arr[] consisting of positive integers of size N. the task is to minimize the overall sum of arr[] by toggling the unset bit (0 bit) of any element of the array for T times, where T is the total number of set bits over all the elements of arr[].
Note: In case of 32-bit integer overflow, return (overall Sum % 1e9 + 7).
Examples:
Input: arr = {2, 2, 2};
Output: 21
Explanation: Binary representation 2 is 10. Since there are total 3 set bit. so, we need to set 3 bits, we can set the lowest unset bits of the every 2s such that they become 11. The total sum is then 3 + 3 + 3 = 9.Input: arr = {3, 3, 7}
Output: 77
Bit Toggling to Minimize Array Sum Using Greedy Technique:
We can use the greedy technique here, we’ll change the rightmost 0s to 1s.
Step-by-step approach:
- Iterate over the elements of the array and count the total set bit T.
-
Again, Iterate over the elements of the array
-
Convert the element into its binary representation and iterate over the bits of binary representation.
- Check for its ith bit is unset or not.
- If the ith bit is unset then, Push the ith position into the array smallestUnsetBit[].
-
Convert the element into its binary representation and iterate over the bits of binary representation.
- Sort the smallestUnsetBit[] array.
- Iterate over the smallestUnsetBit[] for T time and calculate the value for smallestUnsetBit[i] by 2smallestUnsetBit[i] , this value will contribute into the overallSum after toggling smallestUnsetBit[i] bit.
- Return the overallSum.
Below is the implementation of the above approach:
// C++ code to implement the approach: #include <bits/stdc++.h> using namespace std;
#define mod (1e9 + 7) // Function to find the minimum sum int minSum(vector< int >& nums)
{ int T = 0;
// find the total number of set bit.
for ( int i : nums) {
T += __builtin_popcount(i);
}
vector< int > smallestUnsetBit;
// Iterate over the elements of
// given array
for ( auto num : nums) {
// Converting the number to its
// binary representation
string s = bitset<31>(num).to_string();
for ( int i = 30; i >= 0; i--) {
// Check if the ith bit is
// unset of not
if (s[i] == '0' ) {
// Push ith unset bit
// into smallestUnsetBit
smallestUnsetBit.push_back(30 - i);
}
}
}
// Sort the usetbits in
// ascending order.
sort(smallestUnsetBit.begin(), smallestUnsetBit.end());
// Calculate the overall sum
// of given array
long long result
= accumulate(nums.begin(), nums.end(), 0LL);
int i = 0;
// Add the overall effect of sum in
// the result by inverting the '0' bits.
while (T--) {
result
= (result
+ ( long long ) pow (2, smallestUnsetBit[i++]))
% ( long long )mod;
}
// Return the result
return result % ( long long )mod;
} // Driver function int main()
{ vector< int > arr = { 2, 2, 2 };
// Function call
int result = minSum(arr);
cout << result << endl;
return 0;
} |
// Java code to implement the approach import java.util.*;
import java.util.stream.*;
public class Main {
static final int MOD = ( int )1e9 + 7 ;
public static int minSum(List<Integer> nums)
{
int T = 0 ;
// Find the total number of set bits.
for ( int i : nums) {
T += Integer.bitCount(i);
}
List<Integer> smallestUnsetBit = new ArrayList<>();
// Iterate over the elements of the given list
for ( int num : nums) {
// Converting the number to its binary
// representation
String s
= String
.format( "%31s" ,
Integer.toBinaryString(num))
.replace( ' ' , '0' );
for ( int i = 30 ; i >= 0 ; i--) {
// Check if the ith bit is unset or not
if (s.charAt(i) == '0' ) {
// Push the ith unset bit into
// smallestUnsetBit
smallestUnsetBit.add( 30 - i);
}
}
}
// Sort the unset bits in ascending order
Collections.sort(smallestUnsetBit);
// Calculate the overall sum of the given list
long result = nums.stream()
.mapToLong(Integer::longValue)
.sum();
int i = 0 ;
// Add the overall effect of sum by inverting the
// '0' bits
for ( int j = 0 ; j < T; j++) {
result = (result
+ ( long )Math.pow(
2 , smallestUnsetBit.get(i++)))
% MOD;
}
// Return the result
return ( int )(result % MOD);
}
public static void main(String[] args)
{
List<Integer> arr = Arrays.asList( 2 , 2 , 2 );
// Function call
int result = minSum(arr);
System.out.println(result);
}
} // This code is contributed by Abhinav Mahajan // (abhinav_m22). |
def minSum(nums):
mod = int ( 1e9 + 7 )
T = 0
# Find the total number of set bits.
for num in nums:
T + = bin (num).count( '1' )
smallestUnsetBit = []
# Iterate over the elements of the given array
for num in nums:
# Converting the number to its binary representation
s = format (num, '031b' )
for i in range ( 30 , - 1 , - 1 ):
# Check if the ith bit is unset or not
if s[i] = = '0' :
# Push the ith unset bit into smallestUnsetBit
smallestUnsetBit.append( 30 - i)
# Sort the unset bits in ascending order
smallestUnsetBit.sort()
# Calculate the overall sum of the given array
result = sum (nums)
i = 0
# Add the overall effect of sum by inverting the '0' bits
while T > 0 :
result = (result + 2 * * smallestUnsetBit[i]) % mod
i + = 1
T - = 1
# Return the result
return result % mod
# Driver function if __name__ = = "__main__" :
arr = [ 2 , 2 , 2 ]
# Function call
result = minSum(arr)
print (result)
|
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{ static int Mod = 1000000007;
// Function to find the minimum sum
static int MinSum(List< int > nums)
{
int T = 0;
// find the total number of set bit.
foreach ( int num in nums)
{
T += BitCount(num);
}
List< int > smallestUnsetBit = new List< int >();
// Iterate over the elements of given array
foreach ( var num in nums)
{
// Converting the number to its binary representation
string s = Convert.ToString(num, 2).PadLeft(31, '0' );
for ( int j = 30; j >= 0; j--)
{
// Check if the jth bit is unset or not
if (s[j] == '0' )
{
// Push jth unset bit into smallestUnsetBit
smallestUnsetBit.Add(30 - j);
}
}
}
// Sort the unset bits in ascending order.
smallestUnsetBit.Sort();
// Calculate the overall sum of given array
long result = nums.Sum(x => ( long )x);
int index = 0;
// Add the overall effect of sum in the result by inverting the '0' bits.
while (T-- > 0)
{
result = (result + ( long )Math.Pow(2, smallestUnsetBit[index++])) % Mod;
}
// Return the result
return ( int )(result % Mod);
}
// Helper function to count set bits
static int BitCount( int n)
{
int count = 0;
while (n > 0)
{
n &= (n - 1);
count++;
}
return count;
}
// Driver function
static void Main( string [] args)
{
List< int > arr = new List< int > { 2, 2, 2 };
// Function call
int result = MinSum(arr);
Console.WriteLine(result);
}
} |
const mod = 1e9 + 7; // Function to find the minimum sum function minSum(nums) {
let T = 0;
// find the total number of set bits
for (let i of nums) {
T += i.toString(2).split( '1' ).length - 1;
}
let smallestUnsetBit = [];
// Iterate over the elements of given array
for (let num of nums) {
// Converting the number to its binary representation
let s = num.toString(2).padStart(31, '0' );
for (let i = 30; i >= 0; i--) {
// Check if the ith bit is unset or not
if (s[i] === '0' ) {
// Push ith unset bit into smallestUnsetBit
smallestUnsetBit.push(30 - i);
}
}
}
// Sort the unset bits in ascending order
smallestUnsetBit.sort((a, b) => a - b);
// Calculate the overall sum of given array
let result = nums.reduce((acc, curr) => acc + curr, 0);
let i = 0;
// Add the overall effect of sum by inverting the '0' bits
while (T--) {
result = (result + 2 ** smallestUnsetBit[i++]) % mod;
}
// Return the result
return result % mod;
} // Driver code let arr = [2, 2, 2]; // Function call let result = minSum(arr); console.log(result); |
9
Time Complexity: O(N), where N is the length of the given array
Auxiliary Space: O(N)