Given an array arr[] consisting of N integers, the task is to find the maximum Bitwise XOR from all the possible pairs in the given array.
Examples:
Input: arr[] = {25, 10, 2, 8, 5, 3}
Output: 28
Explanation:
The maximum result is 5^25 = 28.
Input: arr[] = {1, 2, 3, 4, 5, 6, 7}
Output: 7
Explanation:
The maximum result is 1^6 = 7.
Naive Approach: Refer to the article Maximum XOR of Two Numbers in an Array for the simplest approach to solve the problem by generating all pairs of the given array and computing XOR of each pair to find the maximum among them.
Time Complexity: O(N2)
Auxiliary Space: O(1)
Bitmasking Approach: Refer to the article Maximum XOR of Two Numbers in an Array to solve the problem using Bitmasking.
Time Complexity: O(N*log M), where M is the maximum number present in the array
Auxiliary Space: O(N)
Efficient Approach: The above approach can be solved by using Trie by inserting the binary representation of the numbers in the array arr[]. Now iterate the binary representation of all the elements in the array arr[] and if the current bit is 0 then find the path with value 1 or vice-versa in the Trie to get the maximum value of Bitwise XOR. Update the maximum value for each number. Below are the steps:
- Initialize maximumXOR as 0.
- Insert the binary representation of all the numbers in the given array arr[] in the Tree. While inserting in the trie if the current bit 0 then create a node in the left else create a node in the right of the current head node.
- Now, traverse the given array and for each element do the following:
- Initialize the currentXOR value as 0.
- Traverse the binary representation of the current number.
- If ith bit is 1 and node->left exists then update currentXOR as currentXOR + pow(2, i) and update node as node->left. Else update node = node->right.
- If ith bit is 0, and node->right exists then update currentXOR as currentXOR + pow(2, i) and update node as node->right. Else update node = node->left.
- For each array element in the above step, update the maximumXOR value if maximumXOR is greater than currentXOR.
- Print the value of maximumXOR after the above steps.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
class node {
public :
node* left;
node* right;
};
void insert( int x, node* head)
{
node* curr = head;
for ( int i = 30; i >= 0; i--) {
int val = (x >> i) & 1;
if (val == 0) {
if (!curr->left)
curr->left = new node();
curr = curr->left;
}
else {
if (!curr->right)
curr->right = new node();
curr = curr->right;
}
}
}
int findMaximumXOR( int arr[], int n)
{
node* head = new node();
for ( int i = 0; i < n; i++) {
insert(arr[i], head);
}
int ans = 0;
for ( int i = 0; i < n; i++) {
int curr_xor = 0;
int M = pow (2, 30);
node* curr = head;
for ( int j = 30; j >= 0; j--) {
int val = (arr[i] >> j) & 1;
if (val == 0) {
if (curr->right) {
curr_xor += M;
curr = curr->right;
}
else {
curr = curr->left;
}
}
else {
if (curr->left) {
curr_xor += M;
curr = curr->left;
}
else {
curr = curr->right;
}
}
M /= 2;
}
ans = max(ans, curr_xor);
}
return ans;
}
int main()
{
int arr[] = { 1, 2, 3, 4 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << findMaximumXOR(arr, N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static class node
{
node left;
node right;
};
static void insert( int x, node head)
{
node curr = head;
for ( int i = 30 ; i >= 0 ; i--)
{
int val = (x >> i) & 1 ;
if (val == 0 )
{
if (curr.left == null )
curr.left = new node();
curr = curr.left;
}
else
{
if (curr.right == null )
curr.right = new node();
curr = curr.right;
}
}
}
static int findMaximumXOR( int arr[], int n)
{
node head = new node();
for ( int i = 0 ; i < n; i++)
{
insert(arr[i], head);
}
int ans = 0 ;
for ( int i = 0 ; i < n; i++)
{
int curr_xor = 0 ;
int M = ( int )Math.pow( 2 , 30 );
node curr = head;
for ( int j = 30 ; j >= 0 ; j--)
{
int val = (arr[i] >> j) & 1 ;
if (val == 0 )
{
if (curr.right != null )
{
curr_xor += M;
curr = curr.right;
}
else
{
curr = curr.left;
}
}
else
{
if (curr.left != null )
{
curr_xor += M;
curr = curr.left;
}
else
{
curr = curr.right;
}
}
M /= 2 ;
}
ans = Math.max(ans, curr_xor);
}
return ans;
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 3 , 4 };
int N = arr.length;
System.out.print(findMaximumXOR(arr, N));
}
}
|
Python3
class node:
def __init__( self ):
self .left = None
self .right = None
def insert(x, head):
curr = head
for i in range ( 30 , - 1 , - 1 ):
val = (x >> i) & 1
if (val = = 0 ):
if (curr.left = = None ):
curr.left = node()
curr = curr.left
else :
if (curr.right = = None ):
curr.right = node()
curr = curr.right
def findMaximumXOR(arr, n):
head = node()
for i in range (n):
insert(arr[i], head)
ans = 0
for i in range (n):
curr_xor = 0
M = 2 * * 30
curr = head
for j in range ( 30 , - 1 , - 1 ):
val = (arr[i] >> j) & 1
if (val = = 0 ):
if (curr.right ! = None ):
curr_xor + = M
curr = curr.right
else :
curr = curr.left
else :
if (curr.left ! = None ):
curr_xor + = M
curr = curr.left
else :
curr = curr.right
M = M / / 2
ans = max (ans, curr_xor)
return ans
arr = [ 1 , 2 , 3 , 4 ]
N = len (arr)
print (findMaximumXOR(arr, N))
|
C#
using System;
class GFG{
public class node
{
public node left;
public node right;
};
static void insert( int x,
node head)
{
node curr = head;
for ( int i = 30; i >= 0; i--)
{
int val = (x >> i) & 1;
if (val == 0)
{
if (curr.left == null )
curr.left = new node();
curr = curr.left;
}
else
{
if (curr.right == null )
curr.right = new node();
curr = curr.right;
}
}
}
static int findMaximumXOR( int []arr,
int n)
{
node head = new node();
for ( int i = 0; i < n; i++)
{
insert(arr[i], head);
}
int ans = 0;
for ( int i = 0; i < n; i++)
{
int curr_xor = 0;
int M = ( int )Math.Pow(2, 30);
node curr = head;
for ( int j = 30; j >= 0; j--)
{
int val = (arr[i] >> j) & 1;
if (val == 0)
{
if (curr.right != null )
{
curr_xor += M;
curr = curr.right;
}
else
{
curr = curr.left;
}
}
else
{
if (curr.left != null )
{
curr_xor += M;
curr = curr.left;
}
else
{
curr = curr.right;
}
}
M /= 2;
}
ans = Math.Max(ans, curr_xor);
}
return ans;
}
public static void Main(String[] args)
{
int []arr = {1, 2, 3, 4};
int N = arr.Length;
Console.Write(findMaximumXOR(arr, N));
}
}
|
Javascript
<script>
class node {
constructor() {
this .left = null ;
this .right = null ;
}
}
function insert(x, head) {
var curr = head;
for (i = 30; i >= 0; i--) {
var val = (x >> i) & 1;
if (val == 0) {
if (curr.left == null )
curr.left = new node();
curr = curr.left;
} else {
if (curr.right == null )
curr.right = new node();
curr = curr.right;
}
}
}
function findMaximumXOR(arr , n) {
var head = new node();
for ( var i = 0; i < n; i++) {
insert(arr[i], head);
}
var ans = 0;
for (i = 0; i < n; i++) {
var curr_xor = 0;
var M = parseInt( Math.pow(2, 30));
var curr = head;
for (j = 30; j >= 0; j--) {
var val = (arr[i] >> j) & 1;
if (val == 0) {
if (curr.right != null ) {
curr_xor += M;
curr = curr.right;
} else {
curr = curr.left;
}
}
else {
if (curr.left != null ) {
curr_xor += M;
curr = curr.left;
} else {
curr = curr.right;
}
}
M = parseInt(M/2);
}
ans = Math.max(ans, curr_xor);
}
return ans;
}
var arr = [ 1, 2, 3, 4 ];
var N = arr.length;
document.write(findMaximumXOR(arr, N));
</script>
|
Time Complexity: O(32*N)
Auxiliary Space: O(32*N)