Find the maximum subset XOR of a given set

04 Nov, 2021
Given an set of positive integers. find the maximum XOR subset value in the given set. Expected time complexity O(n).Examples:
Input: set[] = {2, 4, 5}
Output: 7
The subset {2, 5} has maximum XOR value

Input: set[] = {9, 8, 5}
Output: 13
The subset {8, 5} has maximum XOR value

Input: set[] = {8, 1, 2, 12, 7, 6}
Output: 15
The subset {1, 2, 12} has maximum XOR value

Input: set[] = {4, 6}
Output: 6
The subset {6} has maximum XOR value
Note that this problem is different from the maximum subarray XOR. Here we need to find subset instead of subarray. 
A Simple Solution is to generate all possible subsets of given set, find XOR of every subset and return the subset with maximum XOR.Below is an Efficient Algorithm that works in O(n) time. The idea is based on below facts:  
Number of bits to represent all elements is fixed which is 32 bits for integer in most of the compilers.If maximum element has Most Significant Bit MSB at position i, then result is at least 2i
Number of bits to represent all elements is fixed which is 32 bits for integer in most of the compilers.
If maximum element has Most Significant Bit MSB at position i, then result is at least 2i
 
1. Initialize index of chosen elements as 0. Let this index be 
   'index'
2. Traverse through all bits starting from most significant bit. 
   Let i be the current bit.
......(a) Find the maximum element with i'th bit set.  If there
          is no element with i'th bit set, continue to smaller 
          bit.  
......(b) Let the element with i'th bit set be maxEle and index
          of this element be maxInd. Place maxEle at 'index' and
          (by swapping set[index] and set[maxInd]) 
......(c) Do XOR of maxEle with all numbers having i'th  bit as set.
......(d) Increment index 
3. Return XOR of all elements in set[]. Note that set[] is modified
   in step 2.c.
Below is the implementation of this algorithm. 
C++
Java
Python3
C#
PHP
Javascript
// C++ program to find// maximum XOR subset#include<bits/stdc++.h>using namespace std; // Number of bits to// represent int#define INT_BITS 32 // Function to return// maximum XOR subset// in set[]int maxSubarrayXOR(int set[], int n){    // Initialize index of    // chosen elements    int index = 0;     // Traverse through all    // bits of integer    // starting from the most    // significant bit (MSB)    for (int i = INT_BITS-1; i >= 0; i--)    {        // Initialize index of        // maximum element and        // the maximum element        int maxInd = index;        int maxEle = INT_MIN;        for (int j = index; j < n; j++)        {            // If i'th bit of set[j]            // is set and set[j] is            // greater than max so far.            if ( (set[j] & (1 << i)) != 0                     && set[j] > maxEle )                maxEle = set[j], maxInd = j;        }         // If there was no        // element with i'th        // bit set, move to        // smaller i        if (maxEle == INT_MIN)        continue;         // Put maximum element        // with i'th bit set        // at index 'index'        swap(set[index], set[maxInd]);         // Update maxInd and        // increment index        maxInd = index;         // Do XOR of set[maxIndex]        // with all numbers having        // i'th bit as set.        for (int j=0; j<n; j++)        {            // XOR set[maxInd] those            // numbers which have the            // i'th bit set            if (j != maxInd &&               (set[j] & (1 << i)) != 0)                set[j] = set[j] ^ set[maxInd];        }         // Increment index of        // chosen elements        index++;    }     // Final result is    // XOR of all elements    int res = 0;    for (int i = 0; i < n; i++)        res ^= set[i];    return res;} // Driver programint main(){    int set[] = {9, 8, 5};    int n = sizeof(set) / sizeof(set[0]);         cout << "Max subset XOR is ";    cout << maxSubarrayXOR(set, n);    return 0;}
// Java program to find// maximum XOR subsetimport java.util.*; class GFG {     // Number of bits to// represent intstatic final int INT_BITS = 32; // Function to return// maximum XOR subset// in set[]static int maxSubarrayXOR(int set[], int n){    // Initialize index of    // chosen elements    int index = 0;     // Traverse through all    // bits of integer    // starting from the most    // significant bit (MSB)    for (int i = INT_BITS - 1; i >= 0; i--)    {    // Initialize index of    // maximum element and    // the maximum element    int maxInd = index;    int maxEle = Integer.MIN_VALUE;    for (int j = index; j < n; j++) {                 // If i'th bit of set[j]        // is set and set[j] is        // greater than max so far.        if ((set[j] & (1 << i)) != 0 && set[j] > maxEle)        {        maxEle = set[j];        maxInd = j;        }    }     // If there was no    // element with i'th    // bit set, move to    // smaller i    if (maxEle == -2147483648)        continue;     // Put maximum element    // with i'th bit set    // at index 'index'    int temp = set[index];    set[index] = set[maxInd];    set[maxInd] = temp;     // Update maxInd and    // increment index    maxInd = index;     // Do XOR of set[maxIndex]    // with all numbers having    // i'th bit as set.    for (int j = 0; j < n; j++) {                 // XOR set[maxInd] those        // numbers which have the        // i'th bit set        if (j != maxInd && (set[j] & (1 << i)) != 0)        set[j] = set[j] ^ set[maxInd];    }     // Increment index of    // chosen elements    index++;    }     // Final result is    // XOR of all elements    int res = 0;    for (int i = 0; i < n; i++)    res ^= set[i];    return res;} // Driver codepublic static void main(String arg[]) {    int set[] = {9, 8, 5};    int n = set.length;     System.out.print("Max subset XOR is ");    System.out.print(maxSubarrayXOR(set, n));}} // This code is contributed by Anant Agarwal.
# Python program to find# maximum XOR subset # Number of bits to# represent intINT_BITS=32  # Function to return# maximum XOR subset# in set[]def maxSubarrayXOR(set,n):     # Initialize index of    # chosen elements    index = 0      # Traverse through all    # bits of integer    # starting from the most    # significant bit (MSB)    for i in range(INT_BITS-1,-1,-1):             # Initialize index of        # maximum element and        # the maximum element        maxInd = index        maxEle = -2147483648        for j in range(index,n):                     # If i'th bit of set[j]            # is set and set[j] is            # greater than max so far.            if ( (set[j] & (1 << i)) != 0                     and set[j] > maxEle ):                                 maxEle = set[j]                maxInd = j                 # If there was no        # element with i'th        # bit set, move to        # smaller i        if (maxEle ==-2147483648):            continue          # Put maximum element        # with i'th bit set        # at index 'index'        temp=set[index]        set[index]=set[maxInd]        set[maxInd]=temp          # Update maxInd and        # increment index        maxInd = index          # Do XOR of set[maxIndex]        # with all numbers having        # i'th bit as set.        for j in range(n):                     # XOR set[maxInd] those            # numbers which have the            # i'th bit set            if (j != maxInd and               (set[j] & (1 << i)) != 0):                set[j] = set[j] ^ set[maxInd]                   # Increment index of        # chosen elements        index=index + 1           # Final result is    # XOR of all elements    res = 0    for i in range(n):        res =res ^ set[i]    return res # Driver code set= [9, 8, 5]n =len(set) print("Max subset XOR is ",end="")print(maxSubarrayXOR(set, n)) # This code is contributed# by Anant Agarwal.
// C# program to find// maximum XOR subsetusing System; class GFG{         // Number of bits to    // represent int    static int INT_BITS = 32;         // Function to return    // maximum XOR subset    // in set[]    static int maxSubarrayXOR(int []set,                              int n)    {                 // Initialize index of        // chosen elements        int index = 0;             // Traverse through all        // bits of integer        // starting from the most        // significant bit (MSB)        for (int i = INT_BITS - 1;                 i >= 0; i--)        {                     // Initialize index of        // maximum element and        // the maximum element        int maxInd = index;        int maxEle = int.MinValue;        for (int j = index; j < n; j++)        {                         // If i'th bit of set[j]            // is set and set[j] is            // greater than max so far.            if ((set[j] & (1 << i)) != 0 &&                 set[j] > maxEle)            {                maxEle = set[j];                maxInd = j;            }        }             // If there was no        // element with i'th        // bit set, move to        // smaller i        if (maxEle == -2147483648)            continue;             // Put maximum element        // with i'th bit set        // at index 'index'        int temp = set[index];        set[index] = set[maxInd];        set[maxInd] = temp;             // Update maxInd and        // increment index        maxInd = index;             // Do XOR of set[maxIndex]        // with all numbers having        // i'th bit as set.        for (int j = 0; j < n; j++)        {                     // XOR set[maxInd] those            // numbers which have the            // i'th bit set            if (j != maxInd && (set[j] &               (1 << i)) != 0)            set[j] = set[j] ^ set[maxInd];    }         // Increment index of        // chosen elements        index++;    }     // Final result is    // XOR of all elements        int res = 0;        for (int i = 0; i < n; i++)        res ^= set[i];        return res;    }         // Driver code    public static void Main()    {        int []set = {9, 8, 5};        int n = set.Length;             Console.Write("Max subset XOR is ");        Console.Write(maxSubarrayXOR(set, n));    }} // This code is contributed by Sam007.
<?php// PHP program to find maximum XOR subset // Number of bits to represent int$INT_BITS = 32; // Function to return maximum XOR subset// in set[]function maxSubarrayXOR(&$set, $n){    global $INT_BITS;         // Initialize index of chosen elements    $index = 0;     // Traverse through all bits of integer    // starting from the most significant bit (MSB)    for ($i = $INT_BITS - 1; $i >= 0; $i--)    {        // Initialize index of maximum element        // and the maximum element        $maxInd = $index;        $maxEle = 0;        for ($j = $index; $j < $n; $j++)        {            // If i'th bit of set[j]            // is set and set[j] is            // greater than max so far.            if ( ($set[$j] & (1 << $i)) != 0 &&                  $set[$j] > $maxEle )            {                $maxEle = $set[$j];                $maxInd = $j;            }        }         // If there was no element with i'th        // bit set, move to smaller i        if ($maxEle == 0)        continue;         // Put maximum element with i'th bit        // set at index 'index'        $t = $set[$index];        $set[$index] = $set[$maxInd];        $set[$maxInd] = $t;         // Update maxInd and increment index        $maxInd = $index;         // Do XOR of set[maxIndex] with all numbers        // having i'th bit as set.        for ($j = 0; $j < $n; $j++)        {            // XOR set[maxInd] those numbers which            // have the i'th bit set            if ($j != $maxInd &&               ($set[$j] & (1 << $i)) != 0)                $set[$j] = $set[$j] ^ $set[$maxInd];        }         // Increment index of chosen elements        $index++;    }     // Final result is XOR of all elements    $res = 0;    for ($i = 0; $i < $n; $i++)        $res ^= $set[$i];    return $res;} // Driver Code$set = array(9, 8, 5);$n = sizeof($set);echo "Max subset XOR is ";echo maxSubarrayXOR($set, $n); // This code is contributed by ita_c?>
<script> // Javascript program to find// maximum XOR subset        // Number of bits to    // represent int    let INT_BITS = 32;         // Function to return    // maximum XOR subset    // in set[]    function maxSubarrayXOR(set,n)    {        // Initialize index of        // chosen elements        let index = 0;                 // Traverse through all        // bits of integer        // starting from the most        // significant bit (MSB)                 for (let i = INT_BITS - 1; i >= 0; i--)        {            // Initialize index of            // maximum element and            // the maximum element            let maxInd = index;            let maxEle = Number.MIN_VALUE;            for (let j = index; j < n; j++) {                                   // If i'th bit of set[j]                // is set and set[j] is                // greater than max so far.                if ((set[j] & (1 << i)) != 0 && set[j] > maxEle)                {                maxEle = set[j];                maxInd = j;                }            }                       // If there was no            // element with i'th            // bit set, move to            // smaller i            if (maxEle == Number.MIN_VALUE)                continue;                       // Put maximum element            // with i'th bit set            // at index 'index'            let temp = set[index];            set[index] = set[maxInd];            set[maxInd] = temp;                       // Update maxInd and            // increment index            maxInd = index;                       // Do XOR of set[maxIndex]            // with all numbers having            // i'th bit as set.            for (let j = 0; j < n; j++) {                                   // XOR set[maxInd] those                // numbers which have the                // i'th bit set                if (j != maxInd && (set[j] & (1 << i)) != 0)                    set[j] = set[j] ^ set[maxInd];            }                       // Increment index of            // chosen elements            index++;        }               // Final result is        // XOR of all elements        let res = 0;        for (let i = 0; i < n; i++)            res ^= set[i];        return res;             }         // Driver code    let set=[9, 8, 5];    let n = set.length;    document.write("Max subset XOR is ");    document.write(maxSubarrayXOR(set, n));         //  This code is contributed by avanitrachhadiya2155     </script>
Output: 
Max subset XOR is 13
Time Complexity: O(n)
Auxiliary Space: O(1)
Illustration:  
Let the input set be : {9, 8, 5}

We start from 31st bit [Assuming Integers are 32 bit 
long]. The loop will continue without doing anything till 4'th bit.

The 4th bit is set in set[0] i.e. 9 and this is the maximum
element with 4th bit set. So we choose this element and check
if any other number has the same bit set. If yes, we XOR that 
number with 9. The element set[1], i.e., 8 also has 4'th bit 
set. Now set[] becomes {9, 1, 5}.  We add 9 to the list of 
chosen elements by incrementing 'index'

We move further and find the maximum number with 3rd bit set
which is set[2] i.e. 5  No other number in the array has 3rd
bit set. 5 is also added to the list of chosen element.

We then iterate for bit 2 (no number for this) and then for 
1 which is 1. But numbers 9 and 5 have the 1st bit set. Thus
we XOR 9 and 5 with 1 and our set becomes (8, 1, 4)

Finally, we XOR current elements of set and get the result
as 8 ^ 1 ^ 4 = 13.
How does this work? Let us first understand a simple case when all elements have Most Significant Bits (MSBs) at different positions. The task in this particular case is simple, we need to do XOR of all elements. If input contains multiple numbers with the same MSB, then it’s not obvious which of them we should choose to include in the XOR. What we do is reduce the input list into an equivalent form that doesn’t contain more than one number of the same length. By taking the maximum element, we know that the MSB of this is going to be there in output. Let this MSB be at position i. If there are more elements with i’th set (or same MSB), we XOR them with the maximum number so that the i’th bit becomes 0 in them and problem reduces to i-1 bits. References: http://math.stackexchange.com/questions/48682/maximization-with-xor-operatorNote: The above method is similar to Gaussian elimination. Consider a matrix of size 32 x n where 32 is number of bits and n is number of elements in array. This article is contributed by Ekta Goel. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above 
Sam007
ukasp
avanitrachhadiya2155
rishavmahato348
Bitwise-XOR
Arrays
Bit Magic
Arrays
Bit Magic
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.