Find maximum AND value among all K-size subsets of given Array
Last Updated :
03 May, 2022
Given an array arr[] containing N non-negative integers, the task is to find the maximum AND value among all the subsets having length K.
Examples:
Input: arr[] = {1, 6, 9, 7}, K = 1
Output: 9
Explanation: As only one element is allowed 9 is the greatest value that can be obtained.
Input: arr[] = {3, 3, 3}, K = 2
Output: 3
Input: arr[] = {7, 8, 9, 10, 11, 12}, K = 3
Output: 8
Naive Approach: The simplest approach is to generate all possible subsets of length K and find the maximum AND value subset among them.
Time Complexity: O(2N . N)
Auxiliary Space: O(N)
Efficient Solution: The contribution of a bit at any position is greater than the combined contribution of all the bits to its right. This means the significance of bits matters from left to right (MSB to LSB). So greedily try to get the leftmost bits set first and check the numbers which will help in doing so. Follow the below steps to find the subset of length K having maximum AND value:
- Consider initializing this optimal set with all the values in the array.
- Iterate over all the positions of bits starting from i = 30 to 0.
- Check if there is more than K numbers having their set bit at the ith position
- If there is, update the optimal set with these new set of values (which is nothing but a subset of the optimal set)
- If at any iteration the size of the subset becomes exactly K, break and return that set.
Note: It is also possible that there are more than K values in our set after all the iterations This will simply mean that there are some repeating numbers in set (So they will not affect the answer).
Here is one example that can be considered :
arr[] = {3, 3, 3 }, K = 2
ans = 3 & 3 = 3 (if this optimal set is printed using the below code the answer will be [3, 3, 3] which will not affect the maximum and of the subset)
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maxAndSubset( int arr[], int N, int K)
{
vector< int > optimal_set(arr, arr + N);
for ( int j = 30; j >= 0; j--) {
vector< int > new_optimal_set;
for ( auto element : optimal_set) {
if ((1 << j) & element) {
new_optimal_set.push_back(element);
}
}
if (new_optimal_set.size() < K)
continue ;
optimal_set = new_optimal_set;
if (optimal_set.size() == K)
break ;
}
int ans = (1 << 30) - 1;
for ( auto element : optimal_set) {
ans &= element;
}
return ans;
}
int main()
{
int arr[] = { 7, 8, 9, 10, 11, 12 };
int N = sizeof (arr) / sizeof (arr[0]);
int K = 3;
cout << maxAndSubset(arr, N, K);
return 0;
}
|
Java
import java.util.*;
public class GFG
{
static int maxAndSubset( int arr[], int N, int K)
{
ArrayList<Integer> optimal_set = new ArrayList<Integer>(N);
for ( int i = 0 ; i < N; i++){
optimal_set.add(arr[i]);
}
for ( int j = 30 ; j >= 0 ; j--) {
ArrayList<Integer> new_optimal_set = new ArrayList<Integer>();
for ( int element : optimal_set) {
if ((( 1 << j) & element) == 0 ) {
new_optimal_set.add(element);
}
}
if (new_optimal_set.size() < K)
continue ;
optimal_set = new_optimal_set;
if (optimal_set.size() == K)
break ;
}
int ans = ( 1 << 30 ) - 1 ;
for ( int element : optimal_set) {
ans &= element;
}
return ans;
}
public static void main(String args[])
{
int arr[] = { 7 , 8 , 9 , 10 , 11 , 12 };
int N = arr.length;
int K = 3 ;
System.out.println(maxAndSubset(arr, N, K));
}
}
|
Python3
def maxAndSubset(arr, N, K):
optimal_set = arr.copy()
for j in range ( 30 , - 1 , - 1 ):
new_optimal_set = []
for element in optimal_set:
if (( 1 << j) & element):
new_optimal_set.append(element)
if ( len (new_optimal_set) < K):
continue
optimal_set = new_optimal_set
if ( len (optimal_set) = = K):
break
ans = ( 1 << 30 ) - 1
for element in optimal_set:
ans & = element
return ans
if __name__ = = "__main__" :
arr = [ 7 , 8 , 9 , 10 , 11 , 12 ]
N = len (arr)
K = 3
print (maxAndSubset(arr, N, K))
|
C#
using System;
using System.Collections;
class GFG
{
static int maxAndSubset( int []arr, int N, int K)
{
ArrayList optimal_set = new ArrayList(N);
for ( int i = 0; i < N; i++){
optimal_set.Add(arr[i]);
}
for ( int j = 30; j >= 0; j--) {
ArrayList new_optimal_set = new ArrayList();
foreach ( int element in optimal_set) {
if (((1 << j) & element) == 0) {
new_optimal_set.Add(element);
}
}
if (new_optimal_set.Count < K)
continue ;
optimal_set = new_optimal_set;
if (optimal_set.Count == K)
break ;
}
int ans = (1 << 30) - 1;
foreach ( int element in optimal_set) {
ans &= element;
}
return ans;
}
public static void Main()
{
int []arr = { 7, 8, 9, 10, 11, 12 };
int N = arr.Length;
int K = 3;
Console.WriteLine(maxAndSubset(arr, N, K));
}
}
|
Javascript
<script>
function maxAndSubset(arr, N, K)
{
let optimal_set = [...arr];
for (let j = 30; j >= 0; j--) {
let new_optimal_set = [];
for (let element of optimal_set) {
if ((1 << j) & element) {
new_optimal_set.push(element);
}
}
if (new_optimal_set.length < K)
continue ;
optimal_set = new_optimal_set;
if (optimal_set.length == K)
break ;
}
let ans = (1 << 30) - 1;
for (let element of optimal_set) {
ans &= element;
}
return ans;
}
let arr = [7, 8, 9, 10, 11, 12];
let N = arr.length;
let K = 3;
document.write(maxAndSubset(arr, N, K));
</script>
|
Time Complexity: O(32 * N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...