Minimize the Array sum by inverting 0 bit K times
Last Updated :
06 Dec, 2022
Given an array arr[] of size N and an integer K, the task is to invert the 0 bit (unset bit) of any integer of given array total K times, such that the overall sum of arr gets minimized.
Examples:
Input: arr = {3, 7, 3}, K = 2
Output: 21
Explanation: Binary representation 3 is 11, and 7 is 111.
Since we need to set 2 bits, we can set the lowest unset bits
of the two 3s such that they become 111.
The total sum is then 7 + 7 + 7 = 21.
Input: arr = {2, 3, 4}, K = 2
Output: 11
Approach: Greedy algorithm:
The idea of solving this problem can be done by using the greedy technique. We will change the rightmost 0s to 1s.
Follow the steps below to implement the above idea:
- 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.
- Sort the smallestUnsetBit array.
- Iterate over the smallestUnsetBit for K time and calculate the value for smallestUnsetBit[i] by 2smallestUnsetBit[i], this value will contribute into the overall sum after inverting smallestUnsetBit[i] bit.
- Return the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define mod (1e9 + 7)
int minSum(vector< int >& nums, int k)
{
vector< int > smallestUnsetBit;
for ( auto num : nums) {
string s = bitset<31>(num).to_string();
for ( int i = 30; i >= 0; i--) {
if (s[i] == '0' ) {
smallestUnsetBit.push_back(30 - i);
}
}
}
sort(smallestUnsetBit.begin(),
smallestUnsetBit.end());
long long result
= accumulate(nums.begin(), nums.end(), 0LL);
int i = 0;
while (k--) {
result
= (result
+ ( long long ) pow (2, smallestUnsetBit[i++]))
% ( long long )mod;
}
return result % ( long long )mod;
}
int main()
{
vector< int > arr = { 3, 7, 3 };
int K = 2;
int result = minSum(arr, K);
cout << result << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int minSum(ArrayList<Integer> nums, int k){
ArrayList<Integer> smallestUnsetBit = new ArrayList<>();
for ( int num : nums) {
String s = Integer.toBinaryString(num);
int len = s.length();
for ( int i= 0 ;i< 31 -len;i++){
s = "0" + s;
}
for ( int i = 30 ; i >= 0 ; i--) {
if (s.charAt(i) == '0' ) {
smallestUnsetBit.add( 30 - i);
}
}
}
Collections.sort(smallestUnsetBit);
long result = 0 ;
for ( int i:nums){
result+=i;
}
int i = 0 ;
while (k--> 0 ) {
result = (result + ( long )Math.pow( 2 , smallestUnsetBit.get(i++))) % ( long )(1e+ 7 );
}
return ( int )(result % ( long )(1e+ 7 ));
}
public static void main (String[] args) {
ArrayList<Integer> arr = new ArrayList<>();
arr.add( 3 );
arr.add( 7 );
arr.add( 3 );
int K = 2 ;
int result = minSum(arr, K);
System.out.println(result);
}
}
|
Python3
import math
mod = 1e9 + 7
def minSum(nums, k):
smallestUnsetBit = [];
for num in nums:
s = "{0:032b}" . format (num);
for i in range ( 30 , 1 , - 1 ):
if (s[i] = = '0' ):
smallestUnsetBit.append( 30 - i);
smallestUnsetBit.sort()
result = 0 ;
for num in nums:
result = result + num;
i = 0 ;
while k > = 0 :
result = (result + math. pow ( 2 , smallestUnsetBit[i])) % mod;
k = k - 1 ;
i = i + 1 ;
return result % mod;
arr = [ 3 , 7 , 3 ];
K = 2 ;
result = int (minSum(arr, K));
print (result);
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static int minSum(List< int > nums, int k)
{
List< int > smallestUnsetBit = new List< int >();
foreach ( int num in nums)
{
String s = Convert.ToString(num, 2);
int len = s.Length;
for ( int i = 0; i < 31 - len; i++) {
s = "0" + s;
}
for ( int i = 30; i >= 0; i--) {
if (s[i] == '0' ) {
smallestUnsetBit.Add(30 - i);
}
}
}
smallestUnsetBit.Sort();
long result = 0;
foreach ( int i in nums) { result += i; }
int j = 0;
while (k-- > 0) {
result = (result
+ ( long )Math.Pow(
2, smallestUnsetBit[j++]))
% ( long )(1e+7);
}
return ( int )(result % ( long )(1e+7));
}
static public void Main()
{
List< int > arr = new List< int >();
arr.Add(3);
arr.Add(7);
arr.Add(3);
int K = 2;
int result = minSum(arr, K);
Console.WriteLine(result);
}
}
|
Javascript
<script>
const mod = 1e9 + 7;
const minSum = (nums, k) => {
let smallestUnsetBit = [];
for (let indx in nums) {
let s_next = (nums[indx] >>> 0).toString(2);
let s = "" ;
for (let i = 0; i < 31 - s_next.length; ++i) s += "0" ;
s += s_next;
for (let i = 30; i >= 0; i--) {
if (s[i] == '0' ) {
smallestUnsetBit.push(30 - i);
}
}
}
smallestUnsetBit.sort((a, b) => a - b);
let result = 0;
for (let indx in nums) result += nums[indx];
let i = 0;
while (k--) {
result = (result + Math.pow(2, smallestUnsetBit[i++])) % mod;
}
return result % mod;
}
let arr = [3, 7, 3];
let K = 2;
let result = minSum(arr, K);
document.write(result);
</script>
|
PHP
<?php
function minSum( $nums , $k )
{
$smallestUnsetBit = array ();
foreach ( $nums as $num )
{
$s = str_pad ( decbin ( $num ), 31, '0' , STR_PAD_LEFT);
for ( $i = 30; $i >= 0; $i --)
{
if ( $s [ $i ] == '0' )
{
array_push ( $smallestUnsetBit , 30 - $i );
}
}
}
sort( $smallestUnsetBit );
$result = array_sum ( $nums );
$i = 0;
while ( $k --)
{
$result = ( $result + pow(2, $smallestUnsetBit [ $i ++])) % (PHP_INT_MAX);
}
return $result % (PHP_INT_MAX);
}
$arr = array (3, 7, 3);
$K = 2;
$result = minSum( $arr , $K );
echo $result ;
?>
|
Time Complexity: O(N), where N is the length of the given array
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...