Count distinct possible Bitwise XOR values of subsets of an array

Given an array arr[] consisting of N integers, the task is to find the size of the set S such that Bitwise XOR of any subset of the array arr[] exists in the set S.
Examples:
Input: arr[] = {1, 2, 3, 4, 5}
Output: 8
Explanation:
All possible Bitwise XOR values of subsets of the array arr[] are {0, 1, 2, 3, 4, 5, 6, 7}.
Therefore, the size of the required set is 8.Input: arr[] = {6}
Output: 1
Naive Approach: The simplest approach is to generate all possible non-empty subsets of the given array arr[] and store the Bitwise XOR of all subsets in a set. After generating all the subsets, print the size of the set obtained as the result.
Below is the implementation of the above approach:
C++
// C++ program for the above approachÂ
#include <bits/stdc++.h>using namespace std;Â
// Stores the Bitwise XOR// of every possible subsetunordered_set<int> s;Â
// Function to generate all// combinations of subsets and// store their Bitwise XOR in set Svoid countXOR(int arr[], int comb[],              int start, int end,              int index, int r){    // If the end of the    // subset is reached    if (index == r) {Â
        // Stores the Bitwise XOR        // of the current subset        int new_xor = 0;Â
        // Iterate comb[] to find XOR        for (int j = 0; j < r; j++) {            new_xor ^= comb[j];        }Â
        // Insert the Bitwise        // XOR of R elements        s.insert(new_xor);        return;    }Â
    // Otherwise, iterate to    // generate all possible subsets    for (int i = start;         i <= end && end - i + 1 >= r - index; i++) {        comb[index] = arr[i];Â
        // Recursive call for next index        countXOR(arr, comb, i + 1, end,                 index + 1, r);    }}Â
// Function to find the size of the// set having Bitwise XOR of all the// subsets of the given arrayvoid maxSizeSet(int arr[], int N){    // Iterate over the given array    for (int r = 2; r <= N; r++) {        int comb[r + 1];Â
        // Generate all possible subsets        countXOR(arr, comb, 0, N - 1,                 0, r);    }Â
    // Print the size of the set    cout << s.size() << endl;}Â
// Driver Codeint main(){Â Â Â Â int arr[] = { 1, 2, 3, 4, 5 };Â Â Â Â int N = sizeof(arr) / sizeof(arr[0]);Â
    // Function Call    maxSizeSet(arr, N);Â
    return 0;} |
Java
// Java program for the above approachimport java.io.*;import java.lang.*;import java.util.*;Â
class GFG{Â
// Stores the Bitwise XOR// of every possible subsetstatic HashSet<Integer> s;Â
// Function to generate all// combinations of subsets and// store their Bitwise XOR in set Sstatic void countXOR(int arr[], int comb[],                     int start, int end,                      int index, int r){         // If the end of the    // subset is reached    if (index == r)     {                 // Stores the Bitwise XOR        // of the current subset        int new_xor = 0;Â
        // Iterate comb[] to find XOR        for(int j = 0; j < r; j++)        {            new_xor ^= comb[j];        }Â
        // Insert the Bitwise        // XOR of R elements        s.add(new_xor);        return;    }Â
    // Otherwise, iterate to    // generate all possible subsets    for(int i = start;            i <= end && end - i + 1 >= r - index;             i++)     {        comb[index] = arr[i];Â
        // Recursive call for next index        countXOR(arr, comb, i + 1, end, index + 1, r);    }}Â
// Function to find the size of the// set having Bitwise XOR of all the// subsets of the given arraystatic void maxSizeSet(int arr[], int N){         // Iterate over the given array    for(int r = 1; r <= N; r++)     {        int comb[] = new int[r + 1];Â
        // Generate all possible subsets        countXOR(arr, comb, 0, N - 1, 0, r);    }Â
    // Print the size of the set    System.out.println(s.size());}Â
// Driver Codepublic static void main(String[] args){Â Â Â Â int arr[] = { 1, 2, 3, 4, 5 };Â Â Â Â int N = arr.length;Â
    // Initialize set    s = new HashSet<>();Â
    // Function Call    maxSizeSet(arr, N);}}Â
// This code is contributed by Kingash |
Python3
# Python3 program for the above approachÂ
# Stores the Bitwise XOR# of every possible subsets = set([])Â Â # Function to generate all# combinations of subsets and# store their Bitwise XOR in set Sdef countXOR(arr, comb, start, end, index, r):Â
    # If the end of the    # subset is reached    if (index == r) :          # Stores the Bitwise XOR        # of the current subset        new_xor = 0          # Iterate comb[] to find XOR        for j in range(r):            new_xor ^= comb[j]          # Insert the Bitwise        # XOR of R elements        s.add(new_xor)        return      # Otherwise, iterate to    # generate all possible subsets    i = start    while i <= end and (end - i + 1) >= (r - index):        comb[index] = arr[i]          # Recursive call for next index        countXOR(arr, comb, i + 1, end, index + 1, r)        i += 1  # Function to find the size of the# set having Bitwise XOR of all the# subsets of the given arraydef maxSizeSet(arr, N):Â
    # Iterate over the given array    for r in range(2, N + 1):        comb = [0]*(r + 1)          # Generate all possible subsets        countXOR(arr, comb, 0, N - 1, 0, r)      # Print the size of the set    print(len(s))Â
arr = [ 1, 2, 3, 4, 5 ]N = len(arr)Â
# Function CallmaxSizeSet(arr, N)Â
# This code is contributed by decode2207. |
C#
// C# program for the above approachusing System;using System.Collections.Generic;public class GFG{Â
// Stores the Bitwise XOR// of every possible subsetstatic HashSet<int> s;Â
// Function to generate all// combinations of subsets and// store their Bitwise XOR in set Sstatic void countXOR(int []arr, int []comb,                     int start, int end,                      int index, int r){         // If the end of the    // subset is reached    if (index == r)     {                 // Stores the Bitwise XOR        // of the current subset        int new_xor = 0;Â
        // Iterate comb[] to find XOR        for(int j = 0; j < r; j++)        {            new_xor ^= comb[j];        }Â
        // Insert the Bitwise        // XOR of R elements        s.Add(new_xor);        return;    }Â
    // Otherwise, iterate to    // generate all possible subsets    for(int i = start;            i <= end && end - i + 1 >= r - index;             i++)     {        comb[index] = arr[i];Â
        // Recursive call for next index        countXOR(arr, comb, i + 1, end, index + 1, r);    }}Â
// Function to find the size of the// set having Bitwise XOR of all the// subsets of the given arraystatic void maxSizeSet(int []arr, int N){         // Iterate over the given array    for(int r = 1; r <= N; r++)     {        int []comb = new int[r + 1];Â
        // Generate all possible subsets        countXOR(arr, comb, 0, N - 1, 0, r);    }Â
    // Print the size of the set    Console.WriteLine(s.Count);}Â
// Driver Codepublic static void Main(String[] args){Â Â Â Â int []arr = { 1, 2, 3, 4, 5 };Â Â Â Â int N = arr.Length;Â
    // Initialize set    s = new HashSet<int>();Â
    // Function Call    maxSizeSet(arr, N);}}Â
// This code is contributed by Amit Katiyar |
Javascript
<script>Â
// JavaScript program for the above approachÂ
// Stores the Bitwise XOR// of every possible subsetlet s;Â
// Function to generate all// combinations of subsets and// store their Bitwise XOR in set Sfunction countXOR(arr,comb,start,end,index,r){    // If the end of the    // subset is reached    if (index == r)    {                  // Stores the Bitwise XOR        // of the current subset        let new_xor = 0;          // Iterate comb[] to find XOR        for(let j = 0; j < r; j++)        {            new_xor ^= comb[j];        }          // Insert the Bitwise        // XOR of R elements        s.add(new_xor);        return;    }      // Otherwise, iterate to    // generate all possible subsets    for(let i = start;            i <= end && end - i + 1 >= r - index;            i++)    {        comb[index] = arr[i];          // Recursive call for next index        countXOR(arr, comb, i + 1, end, index + 1, r);    }}Â
// Function to find the size of the// set having Bitwise XOR of all the// subsets of the given arrayfunction maxSizeSet(arr,N){    // Iterate over the given array    for(let r = 1; r <= N; r++)    {        let comb = new Array(r + 1);          // Generate all possible subsets        countXOR(arr, comb, 0, N - 1, 0, r);    }      // Print the size of the set    document.write(s.size);}Â
// Driver Codelet arr=[1, 2, 3, 4, 5 ];let N = arr.length;Â
// Initialize sets = new Set();Â
// Function CallmaxSizeSet(arr, N);Â
// This code is contributed by avanitrachhadiya2155Â
</script> |
8
Â
Time Complexity: O(NN)
Auxiliary Space: O(N)
Efficient approach: The above approach can be optimized by using the Greedy Approach and Gaussian Elimination. Follow the steps below to solve the problem:Â
- Initialize an auxiliary array, say dp[] of size 20, that stores the mask of each array element and initializes it with 0.
- Initialize a variable, say ans as 0, to store the size of the array dp[].
- Traverse the given array arr[] and for each array element arr[], perform the following steps:
- Initialize a variable, say mask as arr[i], to check the position of the most significant set bit.
- If the ith bit from the right of arr[i] is set and dp[i] is 0, then update the array dp[i] as 2i and increment the value of ans by 1 and break out of the loop.
- Otherwise, update the value of the mask as the Bitwise XOR of the mask and dp[i].
- After completing the above steps, print the value of 2ans as the resultant size of the required set of elements.
Below is the implementation of the above approach:Â
C++
// C++ program for the above approach#include <bits/stdc++.h>using namespace std;Â
int const size = 20;Â
// Stores the mask of the vectorint dp[size];Â
// Stores the current size of dp[]int ans;Â
// Function to store the// mask of given integervoid insertVector(int mask){Â Â Â Â // Iterate over the range [0, 20]Â Â Â Â for (int i = 0; i < 20; i++) {Â
        // If i-th bit 0        if ((mask & 1 << i) == 0)            continue;Â
        // If dp[i] is zero        if (!dp[i]) {Â
            // Store the position in dp            dp[i] = mask;Â
            // Increment the answer            ++ans;Â
            // Return from the loop            return;        }Â
        // mask = mask XOR dp[i]        mask ^= dp[i];    }}Â
// Function to find the size of the// set having Bitwise XOR of all the// subset of the given arrayvoid maxSizeSet(int arr[], int N){    // Traverse the array    for (int i = 0; i < N; i++) {        insertVector(arr[i]);    }Â
    // Print the answer    cout << (1 << ans) << endl;}Â
// Driver Codeint main(){Â Â Â Â int arr[] = { 1, 2, 3, 4, 5 };Â Â Â Â int N = sizeof(arr) / sizeof(arr[0]);Â
    // Function Call    maxSizeSet(arr, N);Â
    return 0;} |
Java
// Java program for the above approachclass GFG{Â Â final static int size = 20;Â
  // Stores the mask of the vector  static int[] dp = new int[size];Â
  // Stores the current size of dp[]  static int ans;Â
  // Function to store the  // mask of given integer  static void insertVector(int mask)  {    // Iterate over the range [0, 20]    for (int i = 0; i < 20; i++) {Â
      // If i-th bit 0      if ((mask & 1 << i) == 0)        continue;Â
      // If dp[i] is zero      if (dp[i]==0) {Â
        // Store the position in dp        dp[i] = mask;Â
        // Increment the answer        ++ans;Â
        // Return from the loop        return;      }Â
      // mask = mask XOR dp[i]      mask ^= dp[i];    }  }Â
  // Function to find the size of the  // set having Bitwise XOR of all the  // subset of the given array  static void maxSizeSet(int[] arr, int N)  {         // Traverse the array    for (int i = 0; i < N; i++) {      insertVector(arr[i]);    }Â
    // Print the answer    System.out.println(1<<ans);  }Â
  // Driver code  public static void main(String[] args)  {    int[] arr = { 1, 2, 3, 4, 5 };    int N = arr.length;Â
    // Function Call    maxSizeSet(arr, N);  }}Â
//This code is contributed by Hritik Dwivedi |
Python3
# Python3 program for the above approachÂ
# Stores the mask of the vectordp = [0]*20Â
# Stores the current 20 of dp[]ans = 0Â
# Function to store the# mask of given integerdef insertVector(mask):    global dp, ans         # Iterate over the range [0, 20]    for i in range(20):Â
        # If i-th bit 0        if ((mask & 1 << i) == 0):            continueÂ
        # If dp[i] is zero        if (not dp[i]):Â
            # Store the position in dp            dp[i] = maskÂ
            # Increment the answer            ans += 1Â
            # Return from the loop            returnÂ
        # mask = mask XOR dp[i]        mask ^= dp[i]Â
# Function to find the 20 of the# set having Bitwise XOR of all the# subset of the given arraydef maxSizeSet(arr, N):       # Traverse the array    for i in range(N):        insertVector(arr[i])Â
    # Print the answer    print ((1 << ans))Â
# Driver Codeif __name__ == '__main__':Â Â Â Â arr = [1, 2, 3, 4, 5]Â Â Â Â N = len(arr)Â
    # Function Call    maxSizeSet(arr, N)Â
# This code is contributed by mohit kumar 29. |
C#
// C# program for the above approachusing System;Â
class GFG{Â Â Â Â Â static int size = 20;Â
// Stores the mask of the vectorstatic int[] dp = new int[size];Â
// Stores the current size of dp[]static int ans;Â
// Function to store the// mask of given integerstatic void insertVector(int mask){Â Â Â Â Â Â Â Â Â // Iterate over the range [0, 20]Â Â Â Â for(int i = 0; i < 20; i++) Â Â Â Â {Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // If i-th bit 0Â Â Â Â Â Â Â Â if ((mask & 1 << i) == 0)Â Â Â Â Â Â Â Â Â Â Â Â continue;Â
        // If dp[i] is zero        if (dp[i] == 0)        {                         // Store the position in dp            dp[i] = mask;Â
            // Increment the answer            ++ans;Â
            // Return from the loop            return;        }Â
        // mask = mask XOR dp[i]        mask ^= dp[i];    }}Â
// Function to find the size of the// set having Bitwise XOR of all the// subset of the given arraystatic void maxSizeSet(int[] arr, int N){         // Traverse the array    for(int i = 0; i < N; i++)     {        insertVector(arr[i]);    }Â
    // Print the answer    Console.WriteLine(1 << ans);}Â
// Driver codepublic static void Main(string[] args){Â Â Â Â int[] arr = { 1, 2, 3, 4, 5 };Â Â Â Â int N = arr.Length;Â
    // Function Call    maxSizeSet(arr, N);}}Â
// This code is contributed by ukasp |
Javascript
<script>Â
// Javascript program for the above approachlet size = 20;Â
// Stores the mask of the vectorvar dp = new Array(size).fill(0);Â
// Stores the current size of dp[]let ans = 0;Â
// Function to store the// mask of given integerfunction insertVector(mask){         // Iterate over the range [0, 20]    for(let i = 0; i < 20; i++)     {                 // If i-th bit 0        if ((mask & 1 << i) == 0)            continue;             // If dp[i] is zero        if (dp[i] == 0)        {                         // Store the position in dp            dp[i] = mask;                 // Increment the answer            ++ans;                 // Return from the loop            return;        }             // mask = mask XOR dp[i]        mask ^= dp[i];    }}Â
// Function to find the size of the// set having Bitwise XOR of all the// subset of the given arrayfunction maxSizeSet(arr, N){         // Traverse the array    for(let i = 0; i < N; i++)    {        insertVector(arr[i]);    }         // Print the answer    document.write(1<<ans);}Â
// Driver Codelet arr = [ 1, 2, 3, 4, 5 ];let N = arr.length;Â
// Function CallmaxSizeSet(arr, N);Â
// This code is contributed by nitin_sharma        </script> |
8
Â
Time Complexity: O(M * N)
Auxiliary Space: O(M * N)Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



