【问题标题】:Finding a maximum XOR match寻找最大异或匹配
【发布时间】:2012-02-10 05:17:05
【问题描述】:

我需要你找到一些给定的系列,这些系列与给定的常数具有最大的异或。假设这样:
给定系列: 6 7 8 9 10 给定的常数是 10。10 与其他给定数字的最大异或是 13,即 7。所以我需要找到 7。
现在我遵循标准方法。问题是当我得到 100000 个整数时,我的代码占用了很多时间。有没有其他方法可以有效地找出这个问题?

【问题讨论】:

    标签: math binary


    【解决方案1】:

    我能想到的最快方法是遍历您的数字数组并将它们与您的常数进行异或,通过将它们与您之前找到的最大值进行比较来找到最大值。找到最大数后,只需将其与您的常数再次异或即可找到原始值。

    Java 代码:

    public int findMaximumXOR(int[] nums, int constantNum)
    {
        int largest = nums[0] ^ constantNum;
        for (int i = 1; i<nums.length; ++i)
            if (largest<(nums[i] ^ constantNum))
                largest = (nums[i] ^ constantNum);
    
        return (largest ^ constantNum);
    }
    

    【讨论】:

    • 有什么方法可以直接找到 7(在我的问题中)?有什么算法可以降低复杂度?使用此代码,我只能在 5 秒内完成一个测试用例。
    • 数字序列总是连续的还是随机读入或生成的?因为如果系列没有顺序,那么我认为这是最快的方法,因为您必须遍历数组。
    • 不,排序会让事情变得更糟,因为当你排序时,你会在数组中的数字之间进行一堆比较。如果您正在阅读这些数字,那么您可能会跳过数组并在阅读它们时将它们与最大的进行比较,但我认为这不会有很大帮助。
    • ocf.berkeley.edu/~wwu/cgi-bin/yabb/… 这里有一些与 XOR 最大对有关的东西。但我不明白..看看。
    • 看起来该页面上的解决方案与您提出的问题略有不同。在他们的问题中,您将获得一个随机数数组,并且必须找到当 XOR 一起为您提供最大值的两个。因此,您可以将他们的解决方案(似乎围绕使用二叉树)应用于您的问题,但它会过度复杂化并最终降低效率,因为在构建树的过程中,您再次进行大量比较并且本质上整理东西。
    【解决方案2】:

    a 为数组,q 为数字。

    您首先对给定数组进行排序,然后对 (MAX-q) 执行二进制搜索,其中 MAX 是可能的最大整数 (231-1)。这个想法是,当所有位与数字q 中的位相反时,exor 最大。

    【讨论】:

    • 如果我没有找到 (MAX-q) 怎么办?
    • 即使数组中不存在 MAX-q 也不是问题,我们只需要它在数组中的位置
    【解决方案3】:

    这里可以使用一棵树。

    在输入数字时构造一棵二叉树,MSB 在顶部。

    现在对于每个数字,例如 1011 遍历树 0100...

    在任何时候,如果没有找到理想的恭维,就可以妥协并继续。

    【讨论】:

      【解决方案4】:
      import java.util.Scanner;
      
      public class Solution {
      
      
          public static void main(String[] args) throws Exception{
              Scanner in = new Scanner(System.in);
              int l = in.nextInt();
              int r = in.nextInt();
      
              String ls = Integer.toBinaryString(l);
              String rs = Integer.toBinaryString(r);
      
              if (ls.length() != rs.length()) {
                  System.out.println((int)Math.pow(2, rs.length())-1);        
                  return;
              }
      
              int len = ls.length();      
              int index=0;
      
              for(; index < len; ++index){
                  if (ls.charAt(index) != rs.charAt(index))
                      break;
              }
      
              if (index == len) //l = r
                  System.out.println(0);
              else
                  System.out.println((int)Math.pow(2, len-index)-1);
          }
      }
      

      【讨论】:

      • 我不明白这个解决方案是如何解决上述问题的。你能解释一下吗?
      【解决方案5】:
      int L = 0, R = n-1;
      for(int i = 31; i >= 0 && L < R; i--) {
        if(((a[L]>>i)&1) == ((a[R]>>i)&1))
          continue;
        int l = L, r = R;
        while(r - l > 1) {
          int m = (r+l)/2;
          if((a[m]>>i)&1) r = m;
          else l = m;
        }
        if((b>>i)&1) R = l;
        else L = r;
      }
      

      L 是与数字b 进行异或最大化的数字的索引,而 a 包含按排序顺序排列的数字

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-01
        • 2021-05-12
        • 1970-01-01
        • 1970-01-01
        • 2017-01-21
        • 1970-01-01
        • 2017-02-23
        • 1970-01-01
        相关资源
        最近更新 更多