Find the maximum subarray XOR in a given array
Last Updated :
17 Feb, 2023
Given an array of integers. The task is to find the maximum subarray XOR value in the given array.
Examples:
Input: arr[] = {1, 2, 3, 4}
Output: 7
Explanation: The subarray {3, 4} has maximum XOR value
Input: arr[] = {8, 1, 2, 12, 7, 6}
Output: 15
Explanation: The subarray {1, 2, 12} has maximum XOR value
Input: arr[] = {4, 6}
Output: 6
Explanation: The subarray {6} has maximum XOR value
Naive Approach: Below is the idea to solve the problem:
Create all possible subarrays and calculate the XOR of the subarrays. The maximum among them will be the required answer.
Follow the steps mentioned below to implement the idea:
- Iterate from i = 0 to N-1:
- Initialize a variable (say curr_xor = 0) to store the XOR value of subarrays starting from i
- Run a nested loop from j = i to N-1:
- The value j determines the ending point for the current subarray starting from i.
- Update curr_xor by performing XOR of curr_xor with arr[j].
- If the value is greater than the maximum then update the maximum value also.
- The maximum value is the required answer.
Below is the Implementation of the above approach:
C++
#include<bits/stdc++.h>
using namespace std;
int maxSubarrayXOR( int arr[], int n)
{
int ans = INT_MIN;
for ( int i=0; i<n; i++)
{
int curr_xor = 0;
for ( int j=i; j<n; j++)
{
curr_xor = curr_xor ^ arr[j];
ans = max(ans, curr_xor);
}
}
return ans;
}
int main()
{
int arr[] = {8, 1, 2, 12};
int n = sizeof (arr)/ sizeof (arr[0]);
cout << "Max subarray XOR is " << maxSubarrayXOR(arr, n);
return 0;
}
|
Java
class GFG {
static int maxSubarrayXOR( int arr[], int n)
{
int ans = Integer.MIN_VALUE;
for ( int i= 0 ; i<n; i++)
{
int curr_xor = 0 ;
for ( int j=i; j<n; j++)
{
curr_xor = curr_xor ^ arr[j];
ans = Math.max(ans, curr_xor);
}
}
return ans;
}
public static void main(String args[])
{
int arr[] = { 8 , 1 , 2 , 12 };
int n = arr.length;
System.out.println( "Max subarray XOR is " +
maxSubarrayXOR(arr, n));
}
}
|
Python3
def maxSubarrayXOR(arr,n):
ans = - 2147483648
for i in range (n):
curr_xor = 0
for j in range (i,n):
curr_xor = curr_xor ^ arr[j]
ans = max (ans, curr_xor)
return ans
arr = [ 8 , 1 , 2 , 12 ]
n = len (arr)
print ( "Max subarray XOR is " ,
maxSubarrayXOR(arr, n))
|
C#
using System;
class GFG
{
static int maxSubarrayXOR( int []arr, int n)
{
int ans = int .MinValue;
for ( int i = 0; i < n; i++)
{
int curr_xor = 0;
for ( int j = i; j < n; j++)
{
curr_xor = curr_xor ^ arr[j];
ans = Math.Max(ans, curr_xor);
}
}
return ans;
}
public static void Main()
{
int []arr = {8, 1, 2, 12};
int n = arr.Length;
Console.WriteLine( "Max subarray XOR is " +
maxSubarrayXOR(arr, n));
}
}
|
PHP
<?php
function maxSubarrayXOR( $arr , $n )
{
$ans = PHP_INT_MIN;
for ( $i = 0; $i < $n ; $i ++)
{
$curr_xor = 0;
for ( $j = $i ; $j < $n ; $j ++)
{
$curr_xor = $curr_xor ^ $arr [ $j ];
$ans = max( $ans , $curr_xor );
}
}
return $ans ;
}
$arr = array (8, 1, 2, 12);
$n = count ( $arr );
echo "Max subarray XOR is "
, maxSubarrayXOR( $arr , $n );
?>
|
Javascript
<script>
function maxSubarrayXOR(arr, n)
{
let ans = Number.MIN_VALUE;
for (let i = 0; i < n; i++)
{
let curr_xor = 0;
for (let j = i; j < n; j++)
{
curr_xor = curr_xor ^ arr[j];
ans = Math.max(ans, curr_xor);
}
}
return ans;
}
let arr = [ 8, 1, 2, 12 ];
let n = arr.length;
document.write( "Max subarray XOR is " +
maxSubarrayXOR(arr, n));
</script>
|
Output
Max subarray XOR is 15
Time Complexity: O(N2).
Auxiliary Space: O(1)
Find the maximum subarray XOR in a given array using trie Data Structure.
Maximize the xor subarray by using trie data structure to find the binary inverse of current prefix xor inorder to set the left most unset bits and maximize the value.
Follow the below steps to Implement the idea:
- Create an empty Trie. Every node of Trie is going to contain two children, for 0 and 1 values of a bit.
- Initialize pre_xor = 0 and insert into the Trie, Initialize result = INT_MIN
- Traverse the given array and do the following for every array element arr[i].
- pre_xor = pre_xor ^ arr[i], pre_xor now contains xor of elements from arr[0] to arr[i].
- Query the maximum xor value ending with arr[i] from Trie.
- Update the result if the value obtained above is more than the current value of the result.
Illustration:
It can be observed from the above algorithm that we build a Trie that contains XOR of all prefixes of given array. To find the maximum XOR subarray ending with arr[i], there may be two cases.
- The prefix itself has the maximum XOR value ending with arr[i]. For example if i=2 in {8, 2, 1, 12}, then the maximum subarray xor ending with arr[2] is the whole prefix.
- Remove some prefix (ending at index from 0 to i-1). For example if i=3 in {8, 2, 1, 12}, then the maximum subarray xor ending with arr[3] starts with arr[1] and we need to remove arr[0].
- To find the prefix to be removed, find the entry in Trie that has maximum XOR value with current prefix. If we do XOR of such previous prefix with current prefix, get the maximum XOR value ending with arr[i].
- If there is no prefix to be removed (case i), then we return 0 (that’s why we inserted 0 in Trie).
Below is the implementation of the above idea :
C++
#include<bits/stdc++.h>
using namespace std;
#define INT_SIZE 32
struct TrieNode
{
int value;
TrieNode *arr[2];
};
TrieNode *newNode()
{
TrieNode *temp = new TrieNode;
temp->value = 0;
temp->arr[0] = temp->arr[1] = NULL;
return temp;
}
void insert(TrieNode *root, int pre_xor)
{
TrieNode *temp = root;
for ( int i=INT_SIZE-1; i>=0; i--)
{
bool val = pre_xor & (1<<i);
if (temp->arr[val] == NULL)
temp->arr[val] = newNode();
temp = temp->arr[val];
}
temp->value = pre_xor;
}
int query(TrieNode *root, int pre_xor)
{
TrieNode *temp = root;
for ( int i=INT_SIZE-1; i>=0; i--)
{
bool val = pre_xor & (1<<i);
if (temp->arr[1-val]!=NULL)
temp = temp->arr[1-val];
else if (temp->arr[val] != NULL)
temp = temp->arr[val];
}
return pre_xor^(temp->value);
}
int maxSubarrayXOR( int arr[], int n)
{
TrieNode *root = newNode();
insert(root, 0);
int result = INT_MIN, pre_xor =0;
for ( int i=0; i<n; i++)
{
pre_xor = pre_xor^arr[i];
insert(root, pre_xor);
result = max(result, query(root, pre_xor));
}
return result;
}
int main()
{
int arr[] = {8, 1, 2, 12};
int n = sizeof (arr)/ sizeof (arr[0]);
cout << "Max subarray XOR is " << maxSubarrayXOR(arr, n);
return 0;
}
|
Java
class GFG
{
static final int INT_SIZE = 32 ;
static class TrieNode
{
int value;
TrieNode[] arr = new TrieNode[ 2 ];
public TrieNode() {
value = 0 ;
arr[ 0 ] = null ;
arr[ 1 ] = null ;
}
}
static TrieNode root;
static void insert( int pre_xor)
{
TrieNode temp = root;
for ( int i=INT_SIZE- 1 ; i>= 0 ; i--)
{
int val = (pre_xor & ( 1 <<i)) >= 1 ? 1 : 0 ;
if (temp.arr[val] == null )
temp.arr[val] = new TrieNode();
temp = temp.arr[val];
}
temp.value = pre_xor;
}
static int query( int pre_xor)
{
TrieNode temp = root;
for ( int i=INT_SIZE- 1 ; i>= 0 ; i--)
{
int val = (pre_xor & ( 1 <<i)) >= 1 ? 1 : 0 ;
if (temp.arr[ 1 -val] != null )
temp = temp.arr[ 1 -val];
else if (temp.arr[val] != null )
temp = temp.arr[val];
}
return pre_xor^(temp.value);
}
static int maxSubarrayXOR( int arr[], int n)
{
root = new TrieNode();
insert( 0 );
int result = Integer.MIN_VALUE;
int pre_xor = 0 ;
for ( int i= 0 ; i<n; i++)
{
pre_xor = pre_xor^arr[i];
insert(pre_xor);
result = Math.max(result, query(pre_xor));
}
return result;
}
public static void main(String args[])
{
int arr[] = { 8 , 1 , 2 , 12 };
int n = arr.length;
System.out.println( "Max subarray XOR is " +
maxSubarrayXOR(arr, n));
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
class Trie:
def __init__( self ):
self .root = Node( 0 )
def insert( self , pre_xor):
self .temp = self .root
for i in range ( 31 , - 1 , - 1 ):
val = pre_xor & ( 1 <<i)
if val :
if not self .temp.right:
self .temp.right = Node( 0 )
self .temp = self .temp.right
if not val:
if not self .temp.left:
self .temp.left = Node( 0 )
self .temp = self .temp.left
self .temp.data = pre_xor
def query( self , xor):
self .temp = self .root
for i in range ( 31 , - 1 , - 1 ):
val = xor & ( 1 <<i)
if val:
if self .temp.left:
self .temp = self .temp.left
elif self .temp.right:
self .temp = self .temp.right
else :
if self .temp.right:
self .temp = self .temp.right
elif self .temp.left:
self .temp = self .temp.left
return xor ^ self .temp.data
def maxSubArrayXOR( self , n, Arr):
self .insert( 0 )
result = - float ( 'inf' )
pre_xor = 0
for i in range (n):
pre_xor = pre_xor ^ Arr[i]
self .insert(pre_xor)
result = max (result, self .query(pre_xor))
return result
if __name__ = = "__main__" :
Arr = [ 8 , 1 , 2 , 12 ]
n = len (Arr)
trie = Trie()
print ( "Max subarray XOR is" , end = ' ' )
print (trie.maxSubArrayXOR(n, Arr))
|
C#
using System;
public class GFG
{
public const int INT_SIZE = 32;
public class TrieNode
{
public int value;
public TrieNode[] arr = new TrieNode[2];
public TrieNode()
{
value = 0;
arr[0] = null ;
arr[1] = null ;
}
}
public static TrieNode root;
public static void insert( int pre_xor)
{
TrieNode temp = root;
for ( int i = INT_SIZE-1; i >= 0; i--)
{
int val = (pre_xor & (1 << i)) >= 1 ? 1 : 0;
if (temp.arr[val] == null )
{
temp.arr[val] = new TrieNode();
}
temp = temp.arr[val];
}
temp.value = pre_xor;
}
public static int query( int pre_xor)
{
TrieNode temp = root;
for ( int i = INT_SIZE-1; i >= 0; i--)
{
int val = (pre_xor & (1 << i)) >= 1 ? 1 : 0;
if (temp.arr[1 - val] != null )
{
temp = temp.arr[1 - val];
}
else if (temp.arr[val] != null )
{
temp = temp.arr[val];
}
}
return pre_xor ^ (temp.value);
}
public static int maxSubarrayXOR( int [] arr, int n)
{
root = new TrieNode();
insert(0);
int result = int .MinValue;
int pre_xor = 0;
for ( int i = 0; i < n; i++)
{
pre_xor = pre_xor ^ arr[i];
insert(pre_xor);
result = Math.Max(result, query(pre_xor));
}
return result;
}
public static void Main( string [] args)
{
int [] arr = new int [] {8, 1, 2, 12};
int n = arr.Length;
Console.WriteLine( "Max subarray XOR is " + maxSubarrayXOR(arr, n));
}
}
|
Javascript
const INT_SIZE = 32;
class TrieNode {
constructor() {
this .value = 0;
this .arr = [ null , null ];
}
}
let root;
function insert(pre_xor) {
let temp = root;
for (let i = INT_SIZE - 1; i >= 0; i--) {
let val = (pre_xor & (1 << i)) >= 1 ? 1 : 0;
if (temp.arr[val] === null ) {
temp.arr[val] = new TrieNode();
}
temp = temp.arr[val];
}
temp.value = pre_xor;
}
function query(pre_xor) {
let temp = root;
for (let i = INT_SIZE - 1; i >= 0; i--) {
let val = (pre_xor & (1 << i)) >= 1 ? 1 : 0;
if (temp.arr[1 - val] !== null ) {
temp = temp.arr[1 - val];
}
else if (temp.arr[val] !== null ) {
temp = temp.arr[val];
}
}
return pre_xor ^ temp.value;
}
function maxSubarrayXOR(arr, n) {
root = new TrieNode();
insert(0);
let result = Number.MIN_SAFE_INTEGER;
let pre_xor = 0;
for (let i = 0; i < n; i++) {
pre_xor ^= arr[i];
insert(pre_xor);
result = Math.max(result, query(pre_xor));
}
return result;
}
let arr = [8, 1, 2, 12];
let n = arr.length;
console.log( "Max subarray XOR is " + maxSubarrayXOR(arr, n));
|
Output
Max subarray XOR is 15
Time Complexity: O(N).
Auxiliary Space: O(N)
Exercise: Extend the above solution so that it also prints starting and ending indexes of subarray with maximum value (Hint: we can add one more field to Trie node to achieve this
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...