Concepts Used
Trie
Difficulty Level
Medium
Problem Statement :
Given array of
Nnumbers, we need to find the maximum xor between any pair of the numbers.
Solution Approach :
Introduction :
Idea is to store the numbers in their binary representation. Let’s consider the
Xin bitwise and from the highest bit ofX=>ito lowest bit0. The remaining numbers can be divided into two set one with set(1) bit at the bit position i and the other with unset(0) bit at the bit positioni, if the bit in the ith position ofXis set then we would consider all the numbers with unset bit and neglect the other half similar for when ith bit in theXbeing unset.
Description:
We will use trie to solve this problem.
A Trie is a special data structure used to store strings that can be visualized like a graph. It consists of nodes and edges. Each node consists of atmost26children and edges connect each parent node to its children. These26node pointers is for26letters of the English alphabet. A separate edge is maintained for every edge.
We will build a trie with height being most significant bit of the largest number. To search in the Trie, we start with the first diverging point in the trie. For example, given [9, 10, 14, 13], or [1001, 1010, 1110, 1101], we start with the second bit, because all numbers is set on the first bit. The trie is also a balanced one, because each number is represented by a path whose length is equal to the trie height. For example, given [3, 10, 5, 25, 2, 8], the numbers are represented by 00011, 01010, 00101, 11001, 00010, 01000 in the trie.
Now, the starting point is the first trie node having two diverging sub-tries on the left and on the right. We try to go opposite branches(0 versus 1) in the respective sub-tries whenever possible. Sometimes we have two choices and we try them both, and sometimes we are forced to go in the same branch because that’s the only option.
Algorithm :
insert():
-
iterate for every integer
iin array,arr[], and store the number in its binary representation. -
check if the number (0 or 1) previously being inserted,
-
if not, make a new tree node for this number and add it as the children of the root.
-
it is already present, make the child node as parent and do the same with the remaining bits .
-
After inserting the last bitr node of
iin tree , update the weight of the last bit ofi,(temp->value = key).
maxXOR
-
iterate for every integer
iin array,arr[], -
for every
i, find the current bit in the prefix, -
if there is no same bit then look for opposite bits
-
else, look for prefix which has same bits.
-
return xor value of maximum bit difference value so we get maximum xor value .
-
Update xor value for every
i.
Complexity Analysis :
We are inserting all the elements of array of size
N, lets say. Also we are searching forNintereger values of the array at a time for a single query.
Space complexity of this data structure would beO(2*N), whereNis the length of array.
Solutions:
import java.util.*;
class Main
{
static final int INT_SIZE = 32;
// A Trie Node
static class TrieNode {
int value;
TrieNode[] Child = new TrieNode[2];
public TrieNode()
{
value = 0;
Child[0] = null;
Child[1] = null;
}
}
static TrieNode root;
static void insert(int key)
{
TrieNode temp = root;
for (int i = INT_SIZE - 1; i >= 0; i--) {
int current_bit = (key & (1 << i)) >= 1 ? 1 : 0;
if (temp != null && temp.Child[current_bit] == null)
temp.Child[current_bit] = new TrieNode();
temp = temp.Child[current_bit];
}
temp.value = key;
}
static int maxXORUtil(int key)
{
TrieNode temp = root;
for (int i = INT_SIZE - 1; i >= 0; i--)
{
// Find current bit in given prefix
int current_bit = (key & (1 << i)) >= 1 ? 1 : 0;
if (temp.Child[1-current_bit] != null)
temp = temp.Child[1-current_bit];
else if (temp.Child[ current_bit] != null)
temp = temp.Child[ current_bit];
}
return key ^ temp.value;
}
static int maxXOR(int arr[], int n)
{
int max_xor = Integer.MIN_VALUE;
root = new TrieNode();
insert(arr[0]);
for (int i = 1; i < n; i++) {
max_xor = Math.max(max_xor, maxXORUtil(arr[i]));
insert(arr[i]);
}
return max_xor;
}
public static void main(String args[])
{
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while(t-->0)
{
int n = sc.nextInt();
int []arr = new int[n];
for(int i=0;i
#include#include #include #include #define INT_MIN -9999 typedef struct TrieNode{ struct TrieNode* left; struct TrieNode* right; }; void insert(struct TrieNode* cur, int n) { for(int i=31;i>=0;i--) { int b = (n>>i)&1; if(b) { if(!cur->right) cur->right = (struct TrieNode*)malloc(sizeof(struct TrieNode)); cur = cur->right; } else { if(!cur->left) cur->left = (struct TrieNode*)malloc(sizeof(struct TrieNode)); cur = cur->left; } } } int find(struct TrieNode* head, int nums[],int n) { int max = INT_MIN; for(int i=0;i =0;j--) { int b = (nums[i]>>j)&1; if(b) { if(tmp->left) { cur += pow(2,j); tmp = tmp->left; } else tmp = tmp->right; } else { if(tmp->right) { cur += pow(2,j); tmp = tmp->right; } else tmp = tmp->left; } } if(max
#includeusing namespace std; struct TrieNode{ TrieNode* left; TrieNode* right; }; void insert(TrieNode* cur, int n) { for(int i=31;i>=0;i--) { int b = (n>>i)&1; if(b) { if(!cur->right) cur->right = new TrieNode(); cur = cur->right; } else { if(!cur->left) cur->left = new TrieNode(); cur = cur->left; } } } int find(TrieNode* head, int nums[],int n) { int max = INT_MIN; for(int i=0;i =0;j--) { int b = (nums[i]>>j)&1; if(b) { if(tmp->left) { cur += pow(2,j); tmp = tmp->left; } else tmp = tmp->right; } else { if(tmp->right) { cur += pow(2,j); tmp = tmp->right; } else tmp = tmp->left; } } if(max >t; while(t--) { int n; cin>>n; int num[n]; for(int i=0;i >num[i]; } cout<
class TrieNode:
def __init__(self):
self.left = None
self.right = None
def insert(cur, n):
for i in range(31, -1, -1):
b = (n >> i) & 1
if b:
if not cur.right:
cur.right = TrieNode()
cur = cur.right
else:
if not cur.left:
cur.left = TrieNode()
cur = cur.left
def find(head, nums, n):
max = -float("inf")
for i in range(n):
tmp = head
cur = 0
for j in range(31, -1, -1):
b = (nums[i] >> j) & 1
if b:
if tmp.left:
cur += 2**j
tmp = tmp.left
else:
tmp = tmp.right
else:
if tmp.right:
cur += 2**j
tmp = tmp.right
else:
tmp = tmp.left
if max < cur:
max = cur
return max
def findMaximumXOR(nums, n):
head = TrieNode()
for i in range(n):
insert(head, nums[i])
res = find(head, nums, n)
if res == -float("inf"):
return 0
return res
for _ in range(int(input())):
n = int(input())
nums = list(map(int,input().split()))
print(findMaximumXOR(nums, n))
[forminator_quiz id="2281"]
More references to this problem
This article tried to discuss the concept of Trie. Hope this blog helps you understand and solve the problem. To practice more problems on Trie you can check out .

