273.最大异或和计算 | 豆包MarsCode AI刷题

3 阅读2分钟

中等题:最大异或和计算

问题描述:

给定两个长度为 n 的数组 a 和 b,定义 f(c) 为数组 c 的所有元素的总和。现在,你需要恰好删除数组 a 或者数组 b 中的一个元素,使得 f(a) 和 f(b) 的异或结果最大。请输出这个最大的异或和。

测试样例

样例1:

输入:n = 3,a = [1, 2, 3],b = [3, 2, 1]
输出:5

样例2:

输入:n = 4,a = [4, 5, 6, 7],b = [7, 8, 9, 10]
输出:51

样例3:

输入:n = 5,a = [10, 20, 30, 40, 50],b = [50, 40, 30, 20, 10]
输出:248

解题思路:

我们需要从两个数组 a 和 b 中,恰好删除一个元素,使得剩下两个数组的总和的 异或值 最大。

删除元素后计算异或值:

  • 从a中删除某元素,新的总和就为sum(a) - a[i]
  • 从b中删除某元素,新的总和就为sum(b) - b[i]
  • 对于每一次删除 我们考虑以下两种情况(因为只删除a数组b数组中的一个元素
    • sumA - a[i]) ^ sumB
    • sumA ^ (sumB - b[i])

每一次都更新最大值

算法描述

算法分为以下几步:

  1. 计算初始总和:先求出 sumA 和 sumB。

  2. 遍历数组:依次删除 a 和 b 的每个元素,计算对应的异或值。

  3. 更新最大值:将每次计算的异或值与当前最大值比较,更新最大值。

  4. 返回结果:最终返回最大值。

代码:

def solution(n: int, a: list, b: list) -> int:
    sumA = sum(a)
    sumB = sum(b)

    maxXor = 0

    # 一次遍历数组 a 和 b
    for i in range(n):
        newSumA = sumA - a[i]
        newSumB = sumB - b[i]
        maxXor = max(maxXor, newSumA ^ sumB, sumA ^ newSumB)
    
    return maxXor

复杂度分析:

时间复杂度

  • sum(a)sum(b) 的计算需要 O(n)O(n)
  • 遍历两个数组的删除操作也需要 O(n)O(n)
  • 总时间复杂度为 O(n)O(n)

空间复杂度

  • 使用了固定的临时变量(sumA、sumB、maxXor),不需要额外存储空间。
  • 空间复杂度为 O(1)O(1)

优化?

其实本题的做法就等同于暴力算法,就是一个一个的去循环比较,并且不断更新最大值。那么有没有优于暴力算法的方式呢?

并没有,因为暴力算法的时间复杂度已经等于O(n)O(n)了,因为要从a或b数组中删除一个元素,我们需要至少遍历一次才能得出所有可能的删除结果。因此时间复杂度不可能低于O(n)O(n)

暴力算法通过一次性计算总和(sum(a) 和 sum(b)),然后利用简单的减法和异或运算高效地得到每种删除后的结果。这种方法避免了任何不必要的重复计算。

并且仅仅使用了一些临时变量,并不需要额外的存储空间。