Given an array of integers ,You have to find two elements whose XOR is maximum.
There is naive approach --just by picking each element and xoring with other elemen
This can be solved in O(NlogN)
time complexity using Trie.
arr[i]
element of arr[0, 1, ..... N]
arr[i]
. We know xor of different type of bits(0 ^ 1
or 1 ^ 0
) is always 1
. So during query for each bit, try to traverse node holding opposite bit. This will make that particular bit 1
result in maximizing xor value. If there is no node with opposite bit, only then traverse the same bit node.arr[i]
into trie.For N
elements, we need one query(O(logN)
) and one insertion(O(logN)
) for each element. So the overall time complexity is O(NlogN)
.
You can find nice pictorial explanation on how it works in this thread.
Here is C++ implementation of the above algorithm:
const static int SIZE = 2;
const static int MSB = 30;
class trie {
private:
struct trieNode {
trieNode* children[SIZE];
trieNode() {
for(int i = 0; i < SIZE; ++i) {
children[i] = nullptr;
}
}
~trieNode() {
for(int i = 0; i < SIZE; ++i) {
delete children[i];
children[i] = nullptr;
}
}
};
trieNode* root;
public:
trie(): root(new trieNode()) {
}
~trie() {
delete root;
root = nullptr;
}
void insert(int key) {
trieNode* pCrawl = root;
for(int i = MSB; i >= 0; --i) {
bool bit = (bool)(key & (1 << i));
if(!pCrawl->children[bit]) {
pCrawl->children[bit] = new trieNode();
}
pCrawl = pCrawl->children[bit];
}
}
int query(int key, int& otherKey) {
int Xor = 0;
trieNode *pCrawl = root;
for(int i = MSB; i >= 0; --i) {
bool bit = (bool)(key & (1 << i));
if(pCrawl->children[!bit]) {
pCrawl = pCrawl->children[!bit];
Xor |= (1 << i);
if(!bit) {
otherKey |= (1 << i);
} else {
otherKey &= ~(1 << i);
}
} else {
if(bit) {
otherKey |= (1 << i);
} else {
otherKey &= ~(1 << i);
}
pCrawl = pCrawl->children[bit];
}
}
return Xor;
}
};
pair findMaximumXorElements(vector& arr) {
int n = arr.size();
int maxXor = 0;
pair result;
if(n < 2) return result;
trie* Trie = new trie();
Trie->insert(0); // insert 0 initially otherwise first query won't find node to traverse
for(int i = 0; i < n; i++) {
int elem = 0;
int curr = Trie->query(arr[i], elem);
if(curr > maxXor) {
maxXor = curr;
result = {arr[i], elem};
}
Trie->insert(arr[i]);
}
delete Trie;
return result;
}