Open In App

Find maximum AND value among all K-size subsets of given Array

Last Updated : 03 May, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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:

  1. Consider initializing this optimal set with all the values in the array.
  2. Iterate over all the positions of bits starting from i = 30 to 0.
  3. Check if there is more than K numbers having their set bit at the ith position
  4. If there is, update the optimal set with these new set of values (which is nothing but a subset of the optimal set)
  5. 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++




// 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




// 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




# 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#




// 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.


Javascript




<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>


 
 

Output: 

8

 

 

Time Complexity: O(32 * N)
Auxiliary Space: O(N)

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads