给定一个整数数组,您必须找到两个XOR最大的元素。
有一种幼稚的方法-仅选择每个元素并与其他元素进行异或,然后比较结果以找到该对。
除此之外,还有什么有效的算法吗?
我想我有一个O(n lg U)算法,其中U是最大的数字。这个想法类似于user949300的想法,但有更多细节。
直觉如下。当您将两个数字异或时,要获得最大值,您希望在最高位置上有一个1,然后在此位置上有1的配对中,想要与下一个有1的配对可能的最高位置,等等。
因此算法如下。首先找到数字中任意位置的最高1位(您可以通过对n个数字中的每个数字进行O(lg U)运算,在时间O(n lg U)中进行此操作)。现在,将数组分为两部分- 其中一个数字为1,该组数字为0。任何最佳解决方案都必须将第一个点中带有1的数字与那个点中带有0的数字组合在一起,因为这将使1位尽可能高。任何其他配对那里都有0。
现在,递归地,我们要从1和0组中找到具有最高1的数字对。为此,将这两个组分为四个组:
如果11和00组或10和01组中有任何数字,则它们的XOR是理想的(从11开始)。因此,如果这些组对中的任何一个都不为空,则从这些组递归计算理想解,然后返回这些子问题解的最大值。否则,如果两个组都为空,则意味着所有数字在第二个位置必须具有相同的数字。因此,以1开头的数字和以0开头的数字的最佳XOR运算将导致下一个第二位被抵消,因此我们只看一下第三位。
这给出了以下递归算法,该算法从由其MSB划分的两组数字开始,给出了答案:
要开始使用该算法,您实际上可以将初始组中的数字分为两组-具有MSB 1的数字和具有MSB 0的数字。然后使用两组数字对上述算法进行递归调用。
例如,考虑数字5 1 4 3 02。它们具有表示形式
101 001 100 011 000 010
我们首先将它们分为1组和0组:
101 100 001 011 000 010
现在,我们应用以上算法。我们将其分为11、10、01和00组:
11: 10: 101 100 01: 011 010 00: 000 001
现在,我们无法将任何11个元素与00个元素配对,因此我们只递归10和01组。这意味着我们构造了100、101、010和011组:
101: 101 100: 100 011: 011 010: 010
现在我们只剩下其中一个元素的存储桶,我们只需检查对101和010(给出111)以及100和011(给出111)。这两种方法都适用,因此我们得到的最佳答案是7。
让我们考虑一下该算法的运行时间。注意,最大递归深度为O(lg U),因为数字中只有O(log U)位。在树的每个级别上,每个数字恰好出现在一个递归调用中,并且每个递归调用的确与0和1组中的总数成比例,因为我们需要按位分配它们。因此,递归树中有O(log U)个级别,每个级别都执行O(n),因此总工作量为O(n log U)。
希望这可以帮助!这是一个了不起的问题!