421. 数组中两个数的最大异或值

给定一个非空数组,数组中元素为 a0, a1, a2, … , an-1,其中 0 ≤ ai < 231 。

找到 ai 和aj 最大的异或 (XOR) 运算结果,其中0 ≤ i,  j < n 。

你能在O(n)的时间解决这个问题吗?

示例:

输入: [3, 10, 5, 25, 2, 8]

输出: 28

解释: 最大的结果是 5 ^ 25 = 28.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-xor-of-two-numbers-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

 

class Solution {
public:
    int findMaximumXOR(vector<int>& nums) {
        int res=0,mask=0;
        for(int i=31;i>=0;i--){
            mask|=(1<<i);
            unordered_set<int>s;
            for(auto num:nums){
                s.insert(num&mask);
            }
            int t=res|(1<<i);
            for(auto prefix:s){
                if(s.count(t^prefix)){
                    res=t;
                    break;
                }
            }
        }
        return res;
    }
};

 

 ???

 

 ???

还是国外带佬牛逼

class Solution {
public:
    int findMaximumXOR(vector<int>& nums) {
        int n = nums.size();
        return helper(nums, 0, n-1, 0, n-1, 0, 30);
    }
private:
    // (ls, le) and (rs, re) are two ranges of nums, which gives max xor value to current bit;
    // bit decreases from 30 to 0, i.e., working from most significant bit on the left towards right;
    // Similar to quicksort, partition (ls, le) to two ranges (ls, j-1) and (j, le) by swapping elements
    // the range on the left with current bit = 1, and the range on right is 0; We do the same to (rs, re)
    // In order to set the current bit in the answer, i.e. val, to be 1, the left (ls, le) and right (rs,re) ranges must have subranges with opposite bit. If so, val = (val << 1) + 1; otherwise, val = val << 1.
    int helper(vector<int>& nums, int ls, int le, int rs, int re, int val, int bit) {
        if (bit == -1) return val;
        int mask = 1<<bit, j = ls, k = rs;
        for (int i = ls; i <= le; i++) 
            if (nums[i]&mask) swap(nums[i], nums[j++]);
        for (int i = rs; i <= re; i++) 
            if (nums[i]&mask) swap(nums[i], nums[k++]);
        // the left range has two subranges, the answer is max of (bit 1 subrange on the left and bit 0 subrange on the right) or (bit 0 subrange on the left and bit 1 subrange on the right)
        if (j > ls && j <= le) {
            int ans = 0;
            if (k > rs) 
                ans = helper(nums, j, le, rs, k-1, val*2+1, bit-1);
            if (k <= re) 
                ans = max(ans, helper(nums, ls, j-1, k, re, val*2+1, bit-1));
            return ans;
        }
        // the left range has only bit 0 subrange
        else if (j <= ls) {
            // check whether the right range has bit 1 subrange
            if (k > rs) 
                return helper(nums, ls, le, rs, k-1, val*2+1, bit-1);
            else 
                return helper(nums, ls, le, rs, re, val*2, bit-1);
        }
        // the left range has only bit 1 subrange
        else {
            // check whether the right range has bit 0 subrange
            if (k <= re) 
                return helper(nums, ls, le, k, re, val*2+1, bit-1);
            else 
                return helper(nums, ls, le, rs, re, val*2, bit-1);
        }
    }
};

 

posted @ 2020-11-19 20:37  XXXSANS  阅读(121)  评论(0编辑  收藏  举报