Open In App

Split Array into maximum Subsets with same bitwise AND

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of size N, the task is to find the maximum number of subsets the array can be split such that the bitwise AND of the subsets is the same.

Examples:

Input: N = 4, arr[] = {1, 5, 2, 8}
Output: 2
Explanation:
1st subset -> {1, 8}; bitwise AND = 0 
2nd subset -> {2, 5}; bitwise AND = 0 

Input: N = 3, arr[] = {1, 5, 7}
Output: 1
Explanation: There is no way to split the array into subsets. So all the elements can be considered as a single subset.

Input: N = 5, arr[] = {7, 14, 6, 15, 22}
Output: 3
Explanation: The subsets are {22, 15}, {6} and {7, 14}

Approach: Brute force

Say all the subsets have an equal AND and that is denoted by the variable target. We can find this target value by taking AND of all the elements in the array. This can be proved as follows:

Let’s say the subsets are S1, S2, . . ., Sk, and the bitwise AND of each subset is X. So, S1 & S2 & . . . & Sk = target. As all the elements are part of any one subset, so the bitwise AND of all the elements is also a target.

So the task is to find all the possible combinations of elements to find a maximum number of subsets that can be formed.

Follow the steps mentioned below to implement the idea:

  • We can maintain a mask that represents elements taken till now.
  • If the current element is not present in the mask AND it with the mask and there are 2 options for the element:
    • If after adding the element, AND of the subset is not equal to the target, add this element into the current subset.
    • If after adding element strength, AND of the subset is equal to the target then there can be two possible ways:
      • Add this element to the current subset and start adding elements in a new subset.
      • Keep on adding new elements to the current subset.
  • After adding the current element call the function for adding new elements and decrease the value of n by 1.
  • When n becomes zero, check whether all the subsets have AND equal to the target and then update the answer.
  • Check whether all pairs have equal AND by maintaining a ‘current‘ variable that represents the current AND of elements added in a new subset.
    • If the current has all bits set this means, we have found a pair with AND= target [Because n will be 0 when all elements are used and while calling for a new group the initial AND value passed is the same as the default value stored at the starting].
    • Otherwise, the current subset AND is not equal to AND.

Below is the Implementation of the above approach:

C++




// C++ code to find the max number of pairs
 
#include <bits/stdc++.h>
using namespace std;
int start = 0;
int ans = 0;
 
// Function to find the maximum number of subsets
int solve(int n, int mask, int m, vector<int> arr,
          int target, int current)
{
    // All the elements are used
    if (n == 0) {
 
        // If all the elements are used
        if (current == start) {
            ans = max(ans, m);
            return m;
        }
 
        // If all the elements are used but some elements
        // are not member of any team
        else {
            return 1;
        }
    }
 
    int temp = 0;
    for (int i = 0; i < arr.size(); i++) {
        int j = pow(2, i);
        if (!(mask & j)) {
            int currenttarget = current & arr[i];
 
            // If after taking current element
            // target AND is found
            if (currenttarget == target) {
                int ans1 = solve(n - 1, mask | j, m + 1,
                                 arr, target, start);
                int ans2 = solve(n - 1, mask | j, m, arr,
                                 target, currenttarget);
                temp = max(temp, max(ans1, ans2));
            }
            else {
                temp = max(temp,
                           solve(n - 1, mask | j, m, arr,
                                 target, currenttarget));
            }
        }
    }
    return temp;
}
 
void maxSubset(vector<int>& arr, int N)
{
    int target = arr[0];
    for (int i = 1; i < N; i++)
        target = target & arr[i];
    start = pow(2, 31) - 1;
 
    // Calling function to solve the function
    solve(N, 0, 0, arr, target, start);
}
 
// Driver Code
int main()
{
    vector<int> arr = { 1, 5, 2, 8 };
    int N = arr.size();
 
    // Function call
    maxSubset(arr, N);
 
    cout << ans << endl;
    return 0;
}


Java




// Java code to find the max number of pairs
 
import java.io.*;
 
class GFG {
 
    static int start = 0;
    static int ans = 0;
 
    // Function to find the maximum number of subsets
    static int solve(int n, int mask, int m, int[] arr,
                     int target, int current)
    {
        // All the elements are used
        if (n == 0) {
            // If all the elements are used
            if (current == start) {
                ans = Math.max(ans, m);
                return m;
            }
            // If all the elements are used but some
            // elements are not member of any team
            else {
                return 1;
            }
        }
 
        int temp = 0;
        for (int i = 0; i < arr.length; i++) {
            int j = (int)Math.pow(2, i);
            if ((mask & j) == 0) {
                int currenttarget = current & arr[i];
 
                // If after taking current element target
                // AND is found
                if (currenttarget == target) {
                    int ans1 = solve(n - 1, mask | j, m + 1,
                                     arr, target, start);
                    int ans2
                        = solve(n - 1, mask | j, m, arr,
                                target, currenttarget);
                    temp = Math.max(temp,
                                    Math.max(ans1, ans2));
                }
                else {
                    temp = Math.max(
                        temp, solve(n - 1, mask | j, m, arr,
                                    target, currenttarget));
                }
            }
        }
        return temp;
    }
 
    static void maxSubset(int[] arr, int N)
    {
        int target = arr[0];
        for (int i = 1; i < N; i++) {
            target = target & arr[i];
        }
        start = (int)Math.pow(2, 31) - 1;
 
        // Calling function to solve the function
        solve(N, 0, 0, arr, target, start);
    }
 
    public static void main(String[] args)
    {
        int[] arr = { 1, 5, 2, 8 };
        int N = arr.length;
 
        // Function call
        maxSubset(arr, N);
        System.out.print(ans);
    }
}
 
// This code is contributed by lokeshmvs21.


Python3




# Python code to find the max number of pairs
 
# Function to find the maximum number of subsets
def solve(n, mask, m, arr, target, current, ans):
   
  # All the elements are used
    if n == 0:
       
      # If all the elements are used
        if current == start:
            ans = max(ans, m)
            return m
           
          # If all the elements are used but some
          #  elements are not member of any team
        else:
            return 1
    temp = 0
    for i in range(0, len(arr)):
        j = pow(2, i)
        if not (mask & j):
            currenttarget = current & arr[i]
             
            # If after taking current element target
            # AND is found
            if currenttarget == target:
                ans1 = solve(n - 1, mask | j, m + 1, arr, target, start, ans)
                ans2 = solve(n - 1, mask | j, m, arr,
                             target, currenttarget, ans)
                temp = max(temp, max(ans1, ans2))
            else:
                temp = max(temp, solve(n - 1, mask | j, m,
                                       arr, target, currenttarget, ans))
    return temp
 
 
def maxSubset(arr, N, ans):
    target = arr[0]
    for i in range(1, N):
        target = target & arr[i]
    start = pow(2, 31) - 1
     
    # Calling function to solve the function
    print(solve(N, 0, 0, arr, target, start, ans)-1)
 
# Driver Code
if __name__ == '__main__':
 
    arr = [1, 5, 2, 8]
    N = len(arr)
    # Function Call
    start = 0
    ans = 0
    maxSubset(arr, N, ans)
    # print(ans)
 
    # This code is contributed by vikkycirus.


C#




// C# implementation
using System;
 
public class GFG {
  static int start = 0;
  static int ans = 0;
 
  // Function to find the maximum number of subsets
  public static int solve(int n, int mask, int m,
                          int[] arr, int target,
                          int current)
  {
    // All the elements are used
    if (n == 0) {
 
      // If all the elements are used
      if (current == start) {
        ans = Math.Max(ans, m);
        return m;
      }
 
      // If all the elements are used but some
      // elements are not member of any team
      else {
        return 1;
      }
    }
 
    int temp = 0;
    for (int i = 0; i < arr.Length; i++) {
      int j = (int)(Math.Pow(2, i));
      if ((mask & j) == 0) {
        int currenttarget = current & arr[i];
 
        // If after taking current element
        // target AND is found
        if (currenttarget == target) {
          int ans1 = solve(n - 1, mask | j, m + 1,
                           arr, target, start);
          int ans2
            = solve(n - 1, mask | j, m, arr,
                    target, currenttarget);
          temp = Math.Max(temp,
                          Math.Max(ans1, ans2));
        }
        else {
          temp = Math.Max(
            temp, solve(n - 1, mask | j, m, arr,
                        target, currenttarget));
        }
      }
    }
    return temp;
  }
 
  public static void maxSubset(int[] arr, int N)
  {
    int target = arr[0];
    for (int i = 1; i < N; i++)
      target = target & arr[i];
    start = (int)(Math.Pow(2, 31) - 1);
 
    // Calling function to solve the function
    solve(N, 0, 0, arr, target, start);
  }
 
  static public void Main()
  {
    int[] arr = { 1, 5, 2, 8 };
    int N = arr.Length;
 
    // Function call
    maxSubset(arr, N);
 
    Console.WriteLine(ans);
  }
}
 
// This code is contributed by ksam24000


Javascript




// Javascript code to find the max number of pairs
let start = 0;
let ans = 0;
 
// Function to find the maximum number of subsets
function solve(n, mask,m,arr,target, current)
{
    // All the elements are used
    if (n == 0) {
 
        // If all the elements are used
        if (current == start) {
            ans = Math.max(ans, m);
            return m;
        }
 
        // If all the elements are used but some elements
        // are not member of any team
        else {
            return 1;
        }
    }
 
    let temp = 0;
    for (let i = 0; i < arr.length; i++) {
        let j = Math.pow(2, i);
        if ((mask & j)==0) {
            let currenttarget = current & arr[i];
 
            // If after taking current element
            // target AND is found
            if (currenttarget == target) {
                let ans1 = solve(n - 1, mask | j, m + 1,
                                 arr, target, start);
                let ans2 = solve(n - 1, mask | j, m, arr,
                                 target, currenttarget);
                temp = Math.max(temp, Math.max(ans1, ans2));
            }
            else {
                temp = Math.max(temp,
                           solve(n - 1, mask | j, m, arr,
                                 target, currenttarget));
            }
        }
    }
    return temp;
}
 
function maxSubset( arr,  N)
{
    let target = arr[0];
    for (let i = 1; i < N; i++)
        target = target & arr[i];
    start = Math.pow(2, 31) - 1;
 
    // Calling function to solve the function
    solve(N, 0, 0, arr, target, start);
}
 
 
 
    let arr = [ 1, 5, 2, 8 ];
    let N = arr.length;
 
    // Function call
    maxSubset(arr, N);
 
    console.log(ans);
    
   // This code is contributed by garg28harsh.


Output

2

Time Complexity: O(2N)
Auxiliary Space : O(1)



Last Updated : 29 Nov, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads