Smallest element with K set bits such that sum of Bitwise AND of each array element with K is maximum
Last Updated :
18 Jan, 2023
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++
#include <bits/stdc++.h>
using namespace std;
bool comp(pair< int , int >& a,
pair< int , int >& b)
{
if (a.second != b.second)
return a.second > b.second;
return a.first < b.first;
}
int maximizeSum( int arr[], int n, int k)
{
vector< int > cnt(30, 0);
int X = 0;
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < 30; j++) {
if (arr[i] & (1 << j))
cnt[j]++;
}
}
vector<pair< int , int > > v;
for ( int i = 0; i < 30; i++) {
int gain = cnt[i] * (1 << i);
v.push_back({ i, gain });
}
sort(v.begin(), v.end(), comp);
for ( int i = 0; i < k; i++) {
X |= (1 << v[i].first);
}
cout << X;
}
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
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
static void maximizeSum( int arr[], int n, int k)
{
int cnt[] = new int [ 30 ];
int X = 0 ;
for ( int i = 0 ; i < n; i++)
{
for ( int j = 0 ; j < 30 ; j++)
{
if ((arr[i] & ( 1 << j)) != 0 )
cnt[j]++;
}
}
ArrayList< int []> v = new ArrayList<>();
for ( int i = 0 ; i < 30 ; i++)
{
int gain = cnt[i] * ( 1 << i);
v.add( new int [] { i, gain });
}
Collections.sort(v, (a, b) -> {
if (a[ 1 ] != b[ 1 ])
return b[ 1 ] - a[ 1 ];
return a[ 0 ] - b[ 0 ];
});
for ( int i = 0 ; i < k; i++)
{
X |= ( 1 << v.get(i)[ 0 ]);
}
System.out.println(X);
}
public static void main(String[] args)
{
int arr[] = { 3 , 4 , 5 , 1 };
int K = 1 ;
int N = arr.length;
maximizeSum(arr, N, K);
}
}
|
Python3
def maximize_sum(arr, n, k):
cnt = [ 0 ] * 30
X = 0
for i in range (n):
for j in range ( 30 ):
if arr[i] & ( 1 << j):
cnt[j] + = 1
v = []
for i in range ( 30 ):
gain = cnt[i] * ( 1 << i)
v.append([i, gain])
v.sort(key = lambda x: (x[ 1 ], x[ 0 ]), reverse = True )
for i in range (k):
X | = ( 1 << v[i][ 0 ])
print (X)
arr = [ 3 , 4 , 5 , 1 ]
K = 1
N = len (arr)
maximize_sum(arr, N, K)
|
C#
using System;
using System.Linq;
using System.Collections.Generic;
class GFG
{
static void MaximizeSum( int [] arr, int n, int k)
{
int [] cnt = new int [30];
int X = 0;
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < 30; j++)
{
if ((arr[i] & (1 << j)) != 0)
cnt[j]++;
}
}
List< int []> v = new List< int []>();
for ( int i = 0; i < 30; i++)
{
int gain = cnt[i] * (1 << i);
v.Add( new int [] { i, gain });
}
v.Sort((a, b) =>
{
if (a[1] != b[1])
return b[1] - a[1];
return a[0] - b[0];
});
for ( int i = 0; i < k; i++)
{
X |= (1 << v[i][0]);
}
Console.WriteLine(X);
}
static public void Main( string [] args)
{
int [] arr = { 3, 4, 5, 1 };
int K = 1;
int N = arr.Length;
MaximizeSum(arr, N, K);
}
}
|
Javascript
<script>
function maximizeSum(arr, n, k) {
let cnt = new Array(30).fill(0);
let X = 0;
for (let i = 0; i < n; i++) {
for (let j = 0; j < 30; j++) {
if (arr[i] & (1 << j))
cnt[j]++;
}
}
let v = new Array();
for (let i = 0; i < 30; i++) {
let gain = cnt[i] * (1 << i);
v.push([i, gain]);
}
v.sort((a, b) => {
if (a[1] != b[1])
return b[1] - a[1];
return a[0] - b[0];
});
for (let i = 0; i < k; i++) {
X |= (1 << v[i][0]);
}
document.write(X);
}
let arr = [3, 4, 5, 1];
let K = 1;
let N = arr.length;
maximizeSum(arr, N, K);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...