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: 3Input: 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++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to find the maximum AND // value of all the subsets having length K int maxAndSubset( int arr[], int N, int K)
{ // Initializing the optimal_set
vector< int > optimal_set(arr, arr + N);
// Iterating for every position of bits
for ( int j = 30; j >= 0; j--) {
vector< int > new_optimal_set;
// Checking if the bits at jth
// position can be obtained set
// among the numbers available
// from optimal_set set
for ( auto element : optimal_set) {
if ((1 << j) & element) {
// If bit set at position j,
// add into new_optimal_set
new_optimal_set.push_back(element);
}
}
if (new_optimal_set.size() < K)
continue ;
// Updating optimal_set with new_optimal_set
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;
} // Driver Code 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 program for the above approach import java.util.*;
public class GFG
{ // Function to find the maximum AND
// value of all the subsets having length K
static int maxAndSubset( int arr[], int N, int K)
{
//Initializing the optimal_set
ArrayList<Integer> optimal_set = new ArrayList<Integer>(N);
for ( int i = 0 ; i < N; i++){
optimal_set.add(arr[i]);
}
// Iterating for every position of bits
for ( int j = 30 ; j >= 0 ; j--) {
ArrayList<Integer> new_optimal_set = new ArrayList<Integer>();
// Checking if the bits at jth
// position can be obtained set
// among the numbers available
// from optimal_set set
for ( int element : optimal_set) {
if ((( 1 << j) & element) == 0 ) {
// If bit set at position j,
// add into new_optimal_set
new_optimal_set.add(element);
}
}
if (new_optimal_set.size() < K)
continue ;
// Updating optimal_set with new_optimal_set
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;
}
// Driver Code
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));
}
} // This code is contributed by Samim Hossain Mondal. |
# python3 program for the above approach # Function to find the maximum AND # value of all the subsets having length K def maxAndSubset(arr, N, K):
# Initializing the optimal_set
optimal_set = arr.copy()
# Iterating for every position of bits
for j in range ( 30 , - 1 , - 1 ):
new_optimal_set = []
# Checking if the bits at jth
# position can be obtained set
# among the numbers available
# from optimal_set set
for element in optimal_set:
if (( 1 << j) & element):
# If bit set at position j,
# add into new_optimal_set
new_optimal_set.append(element)
if ( len (new_optimal_set) < K):
continue
# Updating optimal_set with new_optimal_set
optimal_set = new_optimal_set
if ( len (optimal_set) = = K):
break
ans = ( 1 << 30 ) - 1
for element in optimal_set:
ans & = element
return ans
# Driver Code if __name__ = = "__main__" :
arr = [ 7 , 8 , 9 , 10 , 11 , 12 ]
N = len (arr)
K = 3
print (maxAndSubset(arr, N, K))
# This code is contributed by rakeshsahni
|
// C# program for the above approach using System;
using System.Collections;
class GFG
{ // Function to find the maximum AND
// value of all the subsets having length K
static int maxAndSubset( int []arr, int N, int K)
{
// Initializing the optimal_set
ArrayList optimal_set = new ArrayList(N);
for ( int i = 0; i < N; i++){
optimal_set.Add(arr[i]);
}
// Iterating for every position of bits
for ( int j = 30; j >= 0; j--) {
ArrayList new_optimal_set = new ArrayList();
// Checking if the bits at jth
// position can be obtained set
// among the numbers available
// from optimal_set set
foreach ( int element in optimal_set) {
if (((1 << j) & element) == 0) {
// If bit set at position j,
// add into new_optimal_set
new_optimal_set.Add(element);
}
}
if (new_optimal_set.Count < K)
continue ;
// Updating optimal_set with new_optimal_set
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;
}
// Driver Code
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));
}
} // This code is contributed by Samim Hossain Mondal. |
<script> // JavaScript code for the above approach
// Function to find the maximum AND
// value of all the subsets having length K
function maxAndSubset(arr, N, K)
{
// Initializing the optimal_set
let optimal_set = [...arr];
// Iterating for every position of bits
for (let j = 30; j >= 0; j--) {
let new_optimal_set = [];
// Checking if the bits at jth
// position can be obtained set
// among the numbers available
// from optimal_set set
for (let element of optimal_set) {
if ((1 << j) & element) {
// If bit set at position j,
// add into new_optimal_set
new_optimal_set.push(element);
}
}
if (new_optimal_set.length < K)
continue ;
// Updating optimal_set with new_optimal_set
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;
}
// Driver Code
let arr = [7, 8, 9, 10, 11, 12];
let N = arr.length;
let K = 3;
document.write(maxAndSubset(arr, N, K));
// This code is contributed by Potta Lokesh
</script>
|
8
Time Complexity: O(32 * N)
Auxiliary Space: O(N)