Split Array into maximum Subsets with same bitwise AND
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 = 0Input: 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.
2
Time Complexity: O(2N)
Auxiliary Space : O(1)
Please Login to comment...