Given an array arr[] consisting of N integers and integer K, the task is to find the smallest integer X with exactly K set bits such that the sum of Bitwise AND of X with every array element arr[i] is maximum.
Examples:
Input: arr[] = {3, 4, 5, 1}, K = 1
Output: 4
Explanation: Consider the value of X as 4. Then, the sum of Bitwise AND of X and array elements = 4 & 3 + 4 & 4 + 4 & 5 + 4 & 1 = 0 + 4 + 4 + 0 = 8, which is maximum.Input: arr[] = {1, 3, 4, 5, 2, 5}, K = 2
Output: 5
Approach: The given problem can be solved by using the Greedy Approach. Follow the steps below to solve the problem:
- Initialize a variable, say X as 0, to store the resultant value of X.
- Initialize an array, say count[] of size 30, to store at every Ith index, the number array elements having the ith bit set.
- Traverse the given array and if the ith bit is set, then update count[i] by 1.
- Initialize a vector of pairs, say ans, to store the contribution of each bit and values, i.e. if the Ith bit is set, then store the value {i, count[i]2i} in Ans.
- Sort the vector of pairs in descending order of the second elements.
- Traverse the vector Ans over the range [0, K – 1], and update the value of X as the Bitwise OR of X and 2(Ans[i].first).
- After completing the above steps, print the value of X as the result.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Comparator function to sort the // vector of pairs bool comp(pair< int , int >& a,
pair< int , int >& b)
{ // If the second is not the same
// then sort in decreasing order
if (a.second != b.second)
return a.second > b.second;
// Otherwise
return a.first < b.first;
} // Function to find the value of X // such that Bitwise AND of all array // elements with X is maximum int maximizeSum( int arr[], int n, int k)
{ // Stores the count of set bit at
// each position
vector< int > cnt(30, 0);
// Stores the resultant value of X
int X = 0;
// Calculate the count of set bits
// at each position
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < 30; j++) {
// If the jth bit is set
if (arr[i] & (1 << j))
cnt[j]++;
}
}
// Stores the contribution
// of each set bit
vector<pair< int , int > > v;
// Store all bit and amount of
// contribution
for ( int i = 0; i < 30; i++) {
// Find the total contribution
int gain = cnt[i] * (1 << i);
v.push_back({ i, gain });
}
// Sort V[] in decreasing
// order of second parameter
sort(v.begin(), v.end(), comp);
// Choose exactly K set bits
for ( int i = 0; i < k; i++) {
X |= (1 << v[i].first);
}
// Print the answer
cout << X;
} // Driver Code int main()
{ int arr[] = { 3, 4, 5, 1 };
int K = 1;
int N = sizeof (arr) / sizeof (arr[0]);
maximizeSum(arr, N, K);
return 0;
} |
// Java program for the above approach import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
// Function to find the value of X // such that Bitwise AND of all array // elements with X is maximum static void maximizeSum( int arr[], int n, int k)
{ // Stores the count of set bit at
// each position
int cnt[] = new int [ 30 ];
// Stores the resultant value of X
int X = 0 ;
// Calculate the count of set bits
// at each position
for ( int i = 0 ; i < n; i++)
{
for ( int j = 0 ; j < 30 ; j++)
{
// If the jth bit is set
if ((arr[i] & ( 1 << j)) != 0 )
cnt[j]++;
}
}
// Stores the contribution
// of each set bit
ArrayList< int []> v = new ArrayList<>();
// Store all bit and amount of
// contribution
for ( int i = 0 ; i < 30 ; i++)
{
// Find the total contribution
int gain = cnt[i] * ( 1 << i);
v.add( new int [] { i, gain });
}
// Sort V[] in decreasing
// order of second parameter
Collections.sort(v, (a, b) -> {
// If the second is not the same
// then sort in decreasing order
if (a[ 1 ] != b[ 1 ])
return b[ 1 ] - a[ 1 ];
// Otherwise
return a[ 0 ] - b[ 0 ];
});
// Choose exactly K set bits
for ( int i = 0 ; i < k; i++)
{
X |= ( 1 << v.get(i)[ 0 ]);
}
// Print the answer
System.out.println(X);
} // Driver Code public static void main(String[] args)
{ int arr[] = { 3 , 4 , 5 , 1 };
int K = 1 ;
int N = arr.length;
maximizeSum(arr, N, K);
} } // This code is contributed by Kingash |
# Python3 program for the above approach # Function to find the value of X # such that Bitwise AND of all array # elements with X is maximum def maximize_sum(arr, n, k):
# Stores the count of set bit at
# each position
cnt = [ 0 ] * 30
# Stores the resultant value of X
X = 0
# Calculate the count of set bits
# at each position
for i in range (n):
for j in range ( 30 ):
# If the jth bit is set
if arr[i] & ( 1 << j):
cnt[j] + = 1
# Stores the contribution
# of each set bit
v = []
# Store all bit and amount of
# contribution
for i in range ( 30 ):
# Find the total contribution
gain = cnt[i] * ( 1 << i)
v.append([i, gain])
# Sort V[] in decreasing
# order of second parameter
v.sort(key = lambda x: (x[ 1 ], x[ 0 ]), reverse = True )
# Choose exactly K set bits
for i in range (k):
X | = ( 1 << v[i][ 0 ])
# Print the answer
print (X)
# Driver Code arr = [ 3 , 4 , 5 , 1 ]
K = 1
N = len (arr)
maximize_sum(arr, N, K) # This code is contributed by phasing17 |
using System;
using System.Linq;
using System.Collections.Generic;
class GFG
{ // Function to find the value of X such that Bitwise AND of all array elements with X is maximum
static void MaximizeSum( int [] arr, int n, int k)
{
// Stores the count of set bit at each position
int [] cnt = new int [30];
// Stores the resultant value of X
int X = 0;
// Calculate the count of set bits at each position
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < 30; j++)
{
// If the jth bit is set
if ((arr[i] & (1 << j)) != 0)
cnt[j]++;
}
}
// Store all bit and amount of contribution
List< int []> v = new List< int []>();
for ( int i = 0; i < 30; i++)
{
// Find the total contribution
int gain = cnt[i] * (1 << i);
v.Add( new int [] { i, gain });
}
// Sort V[] in decreasing order of second parameter
v.Sort((a, b) =>
{
// If the second is not the same then sort in decreasing order
if (a[1] != b[1])
return b[1] - a[1];
// Otherwise
return a[0] - b[0];
});
// Choose exactly K set bits
for ( int i = 0; i < k; i++)
{
X |= (1 << v[i][0]);
}
// Print the answer
Console.WriteLine(X);
}
// Driver Code
static public void Main( string [] args)
{
int [] arr = { 3, 4, 5, 1 };
int K = 1;
int N = arr.Length;
MaximizeSum(arr, N, K);
}
} |
<script> // JavaScript program for the above approach // Function to find the value of X // such that Bitwise AND of all array // elements with X is maximum function maximizeSum(arr, n, k) {
// Stores the count of set bit at
// each position
let cnt = new Array(30).fill(0);
// Stores the resultant value of X
let X = 0;
// Calculate the count of set bits
// at each position
for (let i = 0; i < n; i++) {
for (let j = 0; j < 30; j++) {
// If the jth bit is set
if (arr[i] & (1 << j))
cnt[j]++;
}
}
// Stores the contribution
// of each set bit
let v = new Array();
// Store all bit and amount of
// contribution
for (let i = 0; i < 30; i++) {
// Find the total contribution
let gain = cnt[i] * (1 << i);
v.push([i, gain]);
}
// Sort V[] in decreasing
// order of second parameter
v.sort((a, b) => {
// If the second is not the same
// then sort in decreasing order
if (a[1] != b[1])
return b[1] - a[1];
// Otherwise
return a[0] - b[0];
});
// Choose exactly K set bits
for (let i = 0; i < k; i++) {
X |= (1 << v[i][0]);
}
// Print the answer
document.write(X);
} // Driver Code let arr = [3, 4, 5, 1]; let K = 1; let N = arr.length; maximizeSum(arr, N, K); </script> |
4
Time Complexity: O(N)
Auxiliary Space: O(1)