Java 中的最大 XOR 值

2024 年 9 月 10 日 | 阅读 8 分钟

我们作为输入接收两个包含非负数的数组。我们的任务是找到 p ^ q 的最大值,其中 p 是第一个数组中的任何元素,q 是第二个数组中的任何元素。除了最大值之外,还要显示给出最大 XOR 值的对。如果有多对给出最大 XOR 值,则打印在第一个输入数组中 p 值先出现的对。

示例 1

输入

int inArr1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
int inArr2[] = {20, 19, 18, 17, 16, 15, 14, 13, 12, 11}

输出

30, 对: 10, 20

解释

对于给定的输入数组,所有可能的对的最大 XOR 值都是 30,它来自第一个数组中的元素 10 和第二个数组中的元素 20。

示例 2

输入

int inArr1[] = {25, 10, 2, 8, 5, 3}
int inArr2[] = {25, 10, 2, 8, 5, 3}

输出

28, 对: 25, 5

解释

对于给定的输入数组,最大 XOR 值是 28,它来自第一个数组中的元素 25 和第二个数组中的元素 5。请注意,如果我们从第一个数组中取元素 5,从第二个数组中取元素 25,我们将得到相同的结果。但是,元素 5 来自第一个数组,并且出现在元素 25 之后。因此,它被避免了。

简单方法:使用嵌套 For 循环

使用嵌套的 for 循环,我们可以找到最大值。外层循环遍历第一个数组。对于外层循环的每次迭代,使用内层 for 循环遍历第二个数组中的每个元素。对于内层循环的每次迭代,分别计算外层和内层 for 循环的循环变量指向的元素之间的 XOR 值。还要将当前的 XOR 值与迄今为止找到的最大 XOR 值进行比较。如果当前 XOR 值大于迄今为止找到的最大 XOR 值,则更新最大 XOR 值。涉及最大 XOR 值的元素是对。

文件名: MaxXorVal.java

输出

The maximum XOR value is: 30
The pair that gives the max XOR value is: (10, 20)


The maximum XOR value is: 28
The pair that gives the max XOR value is: (25, 5)

复杂度分析: 程序使用嵌套的 for 循环,其中外层循环运行 O(m) 时间,对于外层循环的每次迭代,内层循环运行 O(n) 次。因此,程序的时间复杂度为 O(m x n),其中 m 是第一个数组中的总元素数,n 是第二个数组中的总元素数。程序的空间复杂度为 O(1),因为程序不使用任何额外的空间。

现在,是时候进行一些优化了。

方法:使用 TRIE

通过找到那些最左侧位值不同的元素,我们可以实现最大 XOR 值。换句话说,如果取自第一个数组的元素 'P' 的第 j 位的值是 1,那么取自第二个数组的元素 'Q' 的第 j 位应该是 0,反之亦然。为了找到这些元素,我们将从最高有效位(最左侧位)开始,向右移动,直到找到一个位,其值在元素 'P' 和 'Q' 的二进制表示中不同。

为了有效地检查第一个数组中的值,我们可以为第二个数组中的每个元素使用 TRIE 数据结构。对于第二个数组的每个元素,我们进行二进制转换并将每个位插入 TRIE。请注意,根将是最高有效位。

现在,我们将遍历第一个数组的每个元素,将其转换为二进制表示,并从最高有效位开始遍历所有位。如果当前位是 '0',则如果存在,我们移动到 '1' 子节点,反之亦然。最后,我们将找到一个对应的元素,使其与第二个数组的当前元素进行 XOR 运算得到最大值。最后,我们将返回找到的所有此类 XOR 值中的最大值。

文件名: MaxXorVal1.java

输出

The maximum XOR value is: 30
The pair that gives the max XOR value is: (10, 20)


The maximum XOR value is: 28
The pair that gives the max XOR value is: (25, 5)

复杂度分析: 程序使用两个循环,一个用于第一个数组,另一个用于第二个数组。此外,这两个循环不是嵌套的。对于给定数组中的每个数字,我们还运行一个从 32 到 0 的循环。因此,程序的时间复杂度为 O(32 x (m + n))。此外,程序使用 TRIE 数据结构,该结构用于存储第二个数组的 32 位数字。因此,空间复杂度为 O(32 x n),其中 m 是第一个数组的大小,n 是第二个数组的大小。