zoukankan      html  css  js  c++  java
  • 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);
            }
        }
    };
  • 相关阅读:
    ClickHouse 监控及备份 (三)ClickHouse 配置
    ClickHouse 监控及备份 (二)Prometheus&Grafana 的安装
    ClickHouse 监控及备份 (一)ClickHouse 监控概述
    ClickHouse 高级(八)运维(1)常见问题排查
    ClickHouse 高级(七)MaterializeMySQL 引擎
    ClickHouse 高级(六)物化视图
    使用Iperf调整网络
    WinForm中DataGridView的使用(四)
    数据库设计经验总结
    WinForm使用Label控件模拟分割线(竖向)
  • 原文地址:https://www.cnblogs.com/xxxsans/p/14007789.html
Copyright © 2011-2022 走看看