Open In App

Maximum XOR of Two Numbers in an Array | Set 2

Improve
Improve
Like Article
Like
Save
Share
Report

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:

  1. Initialize maximumXOR as 0.
  2. 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.
  3. 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.
  4. For each array element in the above step, update the maximumXOR value if maximumXOR is greater than currentXOR.
  5. Print the value of maximumXOR after the above steps.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Structure of Trie
class node {
public:
    node* left;
    node* right;
};
 
// Function to insert binary
// representation of element x
// in the Trie
void insert(int x, node* head)
{
    // Store the head
    node* curr = head;
 
    for (int i = 30; i >= 0; i--) {
 
        // Find the i-th bit
        int val = (x >> i) & 1;
 
        if (val == 0) {
 
            // If curr->left is NULL
            if (!curr->left)
                curr->left = new node();
 
            // Update curr to curr->left
            curr = curr->left;
        }
        else {
 
            // If curr->right is NULL
            if (!curr->right)
                curr->right = new node();
 
            // Update curr to curr->right
            curr = curr->right;
        }
    }
}
 
// Function that finds the maximum
// Bitwise XOR value for all such pairs
int findMaximumXOR(int arr[], int n)
{
    // head Node of Trie
    node* head = new node();
 
    // Insert each element in trie
    for (int i = 0; i < n; i++) {
        insert(arr[i], head);
    }
 
    // Stores the maximum XOR value
    int ans = 0;
 
    // Traverse the given array
    for (int i = 0; i < n; i++) {
 
        // Stores the XOR with current
        // value arr[i]
        int curr_xor = 0;
 
        int M = pow(2, 30);
 
        node* curr = head;
 
        for (int j = 30; j >= 0; j--) {
 
            // Finding ith bit
            int val = (arr[i] >> j) & 1;
 
            // Check if the bit is 0
            if (val == 0) {
 
                // If right node exists
                if (curr->right) {
 
                    // Update the currentXOR
                    curr_xor += M;
                    curr = curr->right;
                }
 
                else {
                    curr = curr->left;
                }
            }
 
            else {
 
                // Check if left node exists
                if (curr->left) {
 
                    // Update the currentXOR
                    curr_xor += M;
                    curr = curr->left;
                }
                else {
                    curr = curr->right;
                }
            }
 
            // Update M to M/2 for next set bit
            M /= 2;
        }
 
        // Update the maximum XOR
        ans = max(ans, curr_xor);
    }
 
    // Return the maximum XOR found
    return ans;
}
 
// Driver Code
int main()
{
    // Given array arr[]
    int arr[] = { 1, 2, 3, 4 };
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    cout << findMaximumXOR(arr, N);
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Structure of Trie
static class node
{
    node left;
    node right;
};
 
// Function to insert binary
// representation of element x
// in the Trie
static void insert(int x, node head)
{
     
    // Store the head
    node curr = head;
 
    for(int i = 30; i >= 0; i--)
    {
         
        // Find the i-th bit
        int val = (x >> i) & 1;
 
        if (val == 0)
        {
             
            // If curr.left is null
            if (curr.left == null)
                curr.left = new node();
 
            // Update curr to curr.left
            curr = curr.left;
        }
        else
        {
             
            // If curr.right is null
            if (curr.right == null)
                curr.right = new node();
 
            // Update curr to curr.right
            curr = curr.right;
        }
    }
}
 
// Function that finds the maximum
// Bitwise XOR value for all such pairs
static int findMaximumXOR(int arr[], int n)
{
     
    // head Node of Trie
    node head = new node();
 
    // Insert each element in trie
    for(int i = 0; i < n; i++)
    {
        insert(arr[i], head);
    }
 
    // Stores the maximum XOR value
    int ans = 0;
 
    // Traverse the given array
    for(int i = 0; i < n; i++)
    {
         
        // Stores the XOR with current
        // value arr[i]
        int curr_xor = 0;
 
        int M = (int)Math.pow(2, 30);
 
        node curr = head;
 
        for(int j = 30; j >= 0; j--)
        {
             
            // Finding ith bit
            int val = (arr[i] >> j) & 1;
 
            // Check if the bit is 0
            if (val == 0)
            {
 
                // If right node exists
                if (curr.right != null)
                {
                     
                    // Update the currentXOR
                    curr_xor += M;
                    curr = curr.right;
                }
                else
                {
                    curr = curr.left;
                }
            }
 
            else
            {
                 
                // Check if left node exists
                if (curr.left != null)
                {
                     
                    // Update the currentXOR
                    curr_xor += M;
                    curr = curr.left;
                }
                else
                {
                    curr = curr.right;
                }
            }
 
            // Update M to M/2 for next set bit
            M /= 2;
        }
 
        // Update the maximum XOR
        ans = Math.max(ans, curr_xor);
    }
 
    // Return the maximum XOR found
    return ans;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given array arr[]
    int arr[] = { 1, 2, 3, 4 };
 
    int N = arr.length;
 
    // Function call
    System.out.print(findMaximumXOR(arr, N));
}
}
 
// This code is contributed by Amit Katiyar


Python3




# Python program for the above approach
 
# Structure of Trie
class node:
    def __init__(self):
        self.left = None
        self.right = None
 
# Function to insert binary
# representation of element x
# in the Trie
def insert(x,  head):
 
    # Store the head
    curr = head
 
    for i in range(30, -1, -1):
 
        # Find the i-th bit
        val = (x >> i) & 1
 
        if (val == 0):
 
            # If curr.left is null
            if (curr.left == None):
                curr.left = node()
 
            # Update curr to curr.left
            curr = curr.left
        else:
 
            # If curr.right is null
            if (curr.right == None):
                curr.right = node()
 
            # Update curr to curr.right
            curr = curr.right
 
 
# Function that finds the maximum
# Bitwise XOR value for all such pairs
def findMaximumXOR(arr, n):
 
    # head Node of Trie
    head = node()
 
    # Insert each element in trie
    for i in range(n):
        insert(arr[i], head)
 
    # Stores the maximum XOR value
    ans = 0
 
    # Traverse the given array
    for i in range(n):
 
        # Stores the XOR with current
        # value arr[i]
        curr_xor = 0
 
        M = 2 ** 30
 
        curr = head
 
        for j in range(30, -1, -1):
 
            # Finding ith bit
            val = (arr[i] >> j) & 1
 
            # Check if the bit is 0
            if (val == 0):
 
                # If right node exists
                if (curr.right != None):
 
                    # Update the currentXOR
                    curr_xor += M
                    curr = curr.right
                else:
                    curr = curr.left
 
            else:
 
                # Check if left node exists
                if (curr.left != None):
 
                    # Update the currentXOR
                    curr_xor += M
                    curr = curr.left
                else:
                    curr = curr.right
 
            # Update M to M/2 for next set bit
            M = M//2
 
        # Update the maximum XOR
        ans = max(ans, curr_xor)
 
    # Return the maximum XOR found
    return ans
 
# Driver Code
 
# Given array arr
arr = [1, 2, 3, 4]
 
N = len(arr)
 
# Function call
print(findMaximumXOR(arr, N))
 
# This code is contributed by Saurbah Jaiswal


C#




// C# program for
// the above approach
using System;
class GFG{
 
// Structure of Tree
public class node
{
  public node left;
  public node right;
};
 
// Function to insert binary
// representation of element
// x in the Tree
static void insert(int x,
                   node head)
{
  // Store the head
  node curr = head;
 
  for(int i = 30; i >= 0; i--)
  {
    // Find the i-th bit
    int val = (x >> i) & 1;
 
    if (val == 0)
    {
      // If curr.left is null
      if (curr.left == null)
        curr.left = new node();
 
      // Update curr to curr.left
      curr = curr.left;
    }
    else
    {
      // If curr.right is null
      if (curr.right == null)
        curr.right = new node();
 
      // Update curr to curr.right
      curr = curr.right;
    }
  }
}
 
// Function that finds the maximum
// Bitwise XOR value for all
// such pairs
static int findMaximumXOR(int []arr,
                          int n)
{   
  // Head Node of Tree
  node head = new node();
 
  // Insert each element in tree
  for(int i = 0; i < n; i++)
  {
    insert(arr[i], head);
  }
 
  // Stores the maximum XOR value
  int ans = 0;
 
  // Traverse the given array
  for(int i = 0; i < n; i++)
  {
    // Stores the XOR with
    // current value arr[i]
    int curr_xor = 0;
 
    int M = (int)Math.Pow(2, 30);
    node curr = head;
 
    for(int j = 30; j >= 0; j--)
    {
      // Finding ith bit
      int val = (arr[i] >> j) & 1;
 
      // Check if the bit is 0
      if (val == 0)
      {
        // If right node exists
        if (curr.right != null)
        {
          // Update the currentXOR
          curr_xor += M;
          curr = curr.right;
        }
        else
        {
          curr = curr.left;
        }
      }
 
      else
      {
        // Check if left node exists
        if (curr.left != null)
        {
          // Update the currentXOR
          curr_xor += M;
          curr = curr.left;
        }
        else
        {
          curr = curr.right;
        }
      }
 
      // Update M to M/2
      // for next set bit
      M /= 2;
    }
 
    // Update the maximum XOR
    ans = Math.Max(ans, curr_xor);
  }
 
  // Return the maximum
  // XOR found
  return ans;
}
 
// Driver Code
public static void Main(String[] args)
{   
  // Given array []arr
  int []arr = {1, 2, 3, 4};
 
  int N = arr.Length;
 
  // Function call
  Console.Write(findMaximumXOR(arr, N));
}
}
 
// This code is contributed by Rajput-Ji


Javascript




<script>
// javascript program for the above approach
 
    // Structure of Trie
     class node {
         constructor() {
                 
                this.left = null;
                this.right = null;
            }
     }
    // Function to insert binary
    // representation of element x
    // in the Trie
    function insert(x,  head) {
 
        // Store the head
        var curr = head;
 
        for (i = 30; i >= 0; i--) {
 
            // Find the i-th bit
            var val = (x >> i) & 1;
 
            if (val == 0) {
 
                // If curr.left is null
                if (curr.left == null)
                    curr.left = new node();
 
                // Update curr to curr.left
                curr = curr.left;
            } else {
 
                // If curr.right is null
                if (curr.right == null)
                    curr.right = new node();
 
                // Update curr to curr.right
                curr = curr.right;
            }
        }
    }
 
    // Function that finds the maximum
    // Bitwise XOR value for all such pairs
    function findMaximumXOR(arr , n) {
 
        // head Node of Trie
        var head = new node();
 
        // Insert each element in trie
        for (var i = 0; i < n; i++) {
            insert(arr[i], head);
        }
 
        // Stores the maximum XOR value
        var ans = 0;
 
        // Traverse the given array
        for (i = 0; i < n; i++) {
 
            // Stores the XOR with current
            // value arr[i]
            var curr_xor = 0;
 
            var M = parseInt( Math.pow(2, 30));
 
            var curr = head;
 
            for (j = 30; j >= 0; j--) {
 
                // Finding ith bit
                var val = (arr[i] >> j) & 1;
 
                // Check if the bit is 0
                if (val == 0) {
 
                    // If right node exists
                    if (curr.right != null) {
 
                        // Update the currentXOR
                        curr_xor += M;
                        curr = curr.right;
                    } else {
                        curr = curr.left;
                    }
                }
 
                else {
 
                    // Check if left node exists
                    if (curr.left != null) {
 
                        // Update the currentXOR
                        curr_xor += M;
                        curr = curr.left;
                    } else {
                        curr = curr.right;
                    }
                }
 
                // Update M to M/2 for next set bit
                M = parseInt(M/2);
            }
 
            // Update the maximum XOR
            ans = Math.max(ans, curr_xor);
        }
 
        // Return the maximum XOR found
        return ans;
    }
 
    // Driver Code
     
 
        // Given array arr
        var arr = [ 1, 2, 3, 4 ];
 
        var N = arr.length;
 
        // Function call
        document.write(findMaximumXOR(arr, N));
 
// This code is contributed by umadevi9616
</script>


Output: 

7

 

Time Complexity: O(32*N)
Auxiliary Space: O(32*N)



Last Updated : 20 Jun, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads