Two elements in array whose xor is maximum

后端 未结 6 1513
野趣味
野趣味 2020-12-22 16:35

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

6条回答
  •  伪装坚强ぢ
    2020-12-22 17:22

    This can be solved in O(NlogN) time complexity using Trie.

    • Construct a trie. For each integer key, each node of the trie will hold every bit(0 or 1) starting from most significant bit.
    • Now for each arr[i] element of arr[0, 1, ..... N]
      • Perform query to retrieve the maximum xor value possible for 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.
      • After query, insert arr[i] into trie.
      • For each element, keep track the maximum Xor value possible.
      • During walking through each node, build the other key for which the Xor is being maximized.

    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;
    }
    

提交回复
热议问题