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

484 阅读1分钟

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

给你一个整数数组 nums ,返回 nums[i] XOR nums[j] 的最大运算结果,其中 0 ≤ i ≤ j < n 。

进阶:你可以在 O(n) 的时间解决这个问题吗?

示例 1:

输入:nums = [3,10,5,25,2,8]
输出:28
解释:最大运算结果是 5 XOR 25 = 28.

示例 2:

输入:nums = [0]
输出:0

思路

  • 首先想到的是暴力法,在时复杂度o(n)中获取最大值返回即可,如解法一。
  • 本题的进阶思想是,要保证时间复杂度为o(n)。关于异或运算的问题,常常会使用到一个异或运算规则,如下所示:
a^b=c 则a=b^c,也可以得到b=a^c
  • 在本题中,在二进制中,要得到最大的运算结果,就要使得最高位为1。
  • 结合上述的异或运算规则,a^b=maxValue,可得到a=maxValue^b。因此,在此题中,我们需要做的就是获取“最大值”(二进制的最高位为1)数组,然后“最大值”分别与数组中所有值异或。
  • 在上述结果数组中获取最大值,如解法二。

解法一

func findMaximumXOR(nums []int) int {
    maxValue:=0 // 定义输出结果变量
    for i:=0;i<len(nums)-1;i++{
        for j:=i+1;j<len(nums);j++{
            cur:=nums[i]^nums[j]
            if cur>maxValue{
                maxValue=cur
            }
        }
    } //在双层循环中获取最大值,并给输出结果变量赋值
    return maxValue
}

解法二

func findMaximumXOR(nums []int) int {
    temp:=0 // 定义临时变量,存放
    for _,v:=range nums{// 数组中的各个数值依次求或
        temp|=v
    }
    if temp==0{ // 如果值为0,说明此时不存在最高位为1,则返回0
        return 0
    }
    count:=0 //定义计位变量,用来记录最高位为1的位置
    for temp!=1{ // 获取count的值
        temp>>=1
        count++
    }
    target:=1<<count // 根据count,先假设一个和最大值类似(二进制的最高位为1)的变量
    res:=[]int{} // 定义”最高位为1“的数组
    for _,v:=range nums{ // 遍历数组,当前元素和target的&按位与运算,若结果等于target,则存入
        if v&target==target{
            res=append(res,v)
        }
    }
    maxValue:=0 // 定义输出结果的变量
    for _,v1:=range nums{
        for _,v2:=range res{
            cur:=v1^v2
            if cur>=maxValue{
                maxValue=cur
            }
        }
    } // 将“最大值”数组和数组元素依次异或,返回最大值maxValue
    return maxValue
}