Trie (3) -- Maximum XOR of Two Numbers in an Array

来源:互联网 发布:知乎 果壳中的宇宙 编辑:程序博客网 时间:2024/06/06 09:02

Maximum XOR of Two Numbers in an Array

Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231.

Find the maximum result of ai XOR aj, where 0 ≤ ij < n.

Could you do this in O(n) runtime?

Example:

Input: [3, 10, 5, 25, 2, 8]Output: 28Explanation: The maximum result is 5 ^ 25 = 28.


解法1:Trie树。

1. 将所有的数字按bit从高到低建树。

2. 将所有的数字在Trie上进行查询,每当可以有bit相异,则该数字可产生的最大XOR rst <<= 1 且 rst |= 1。


    struct TrieNode{        TrieNode* next[2];        TrieNode() {            memset(next, NULL, sizeof(next));        }    };    TrieNode* buildTree(vector<int>& nums){        TrieNode* root = new TrieNode();        TrieNode* p;        for (int num : nums){            p = root;            for (int i = 31; i >= 0; i--){                int index = num >> i & 1;                if (p -> next[index] == NULL){                    p = p -> next[index] = new TrieNode();                }                else p = p -> next[index];            }        }        return root;    }    int findMax(TrieNode* root, int num){        int rst = 0;        TrieNode* p = root;        for (int i = 31; i >= 0; i--){            int index = num >> i & 1 ? 0 : 1; //取与该数字bit位相异的index            rst <<= 1;            if (p -> next[index] != NULL){                rst |= 1;    //将新增加的低位置1                p = p -> next[index];            }            else p = p -> next[1-index];        }        return rst;    }    int findMaximumXOR(vector<int>& nums) {        TrieNode* root = buildTree(nums);        int maxRst = 0;        for (int num : nums){            maxRst = max(maxRst, findMax(root, num));        }        return maxRst;    }


解法2:每次迭代确定最后的结果一个bit。

int findMaximumXOR(vector<int>& nums) {        int max = 0, mask = 0;        unordered_set<int> t;        // search from left to right, find out for each bit is there         // two numbers that has different value        for (int i = 31; i >= 0; i--){            // mask contains the bits considered so far            mask |= (1 << i);            t.clear();            // store prefix of all number with right i bits discarded            for (int n: nums){                t.insert(mask & n);            }                        // now find out if there are two prefix with different i-th bit            // if there is, the new max should be current max with one 1 bit at i-th position, which is candidate            // and the two prefix, say A and B, satisfies:            // A ^ B = candidate            // so we also have A ^ candidate = B or B ^ candidate = A            // thus we can use this method to find out if such A and B exists in the set 
    // the final result must be obtained by prefix in the set.
            int candidate = max | (1<<i);            for (int prefix : t){                if (t.find(prefix ^ candidate) != t.end()){                    max = candidate;                    break;                }                           }        }        return max;    }


0 0
原创粉丝点击