LeetCode 题解工作台

两个数组最小的异或值之和

给你两个整数数组 nums1 和 nums2 ,它们长度都为 n 。 两个数组的 异或值之和 为 (nums1[0] XOR nums2[0]) + (nums1[1] XOR nums2[1]) + ... + (nums1[n - 1] XOR nums2[n - 1]) ( 下标从 0 开始 …

category

4

题型

code_blocks

5

代码语言

hub

3

相关题

当前训练重点

困难 · 状态·转移·动态规划

bolt

答案摘要

我们注意到 $n \leq 14$,因此,我们可以考虑使用状态压缩动态规划的方法求解本题。 我们用一个长度为 的二进制数表示当前的状态,第 位为 表示 已经被选择,为 表示 还未被选择。

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 状态·转移·动态规划 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你两个整数数组 nums1 和 nums2 ,它们长度都为 n 。

两个数组的 异或值之和 为 (nums1[0] XOR nums2[0]) + (nums1[1] XOR nums2[1]) + ... + (nums1[n - 1] XOR nums2[n - 1]) (下标从 0 开始)。

  • 比方说,[1,2,3] 和 [3,2,1] 的 异或值之和 等于 (1 XOR 3) + (2 XOR 2) + (3 XOR 1) = 2 + 0 + 2 = 4 。

请你将 nums2 中的元素重新排列,使得 异或值之和 最小 。

请你返回重新排列之后的 异或值之和 。

 

示例 1:

输入:nums1 = [1,2], nums2 = [2,3]
输出:2
解释:nums2 重新排列得到 [3,2] 。
异或值之和为 (1 XOR 3) + (2 XOR 2) = 2 + 0 = 2 。

示例 2:

输入:nums1 = [1,0,3], nums2 = [5,3,4]
输出:8
解释:nums2 重新排列得到 [5,4,3] 。
异或值之和为 (1 XOR 5) + (0 XOR 4) + (3 XOR 3) = 4 + 4 + 0 = 8 。

 

提示:

  • n == nums1.length
  • n == nums2.length
  • 1 <= n <= 14
  • 0 <= nums1[i], nums2[i] <= 107
lightbulb

解题思路

方法一:状态压缩动态规划

我们注意到 n14n \leq 14,因此,我们可以考虑使用状态压缩动态规划的方法求解本题。

我们用一个长度为 nn 的二进制数表示当前的状态,第 ii 位为 11 表示 nums2[i]nums2[i] 已经被选择,为 00 表示 nums2[i]nums2[i] 还未被选择。

我们定义 f[i][j]f[i][j] 表示 nums1nums1 的前 ii 个数中,选择了 nums2nums2ii 个数,且当前所选数字的状态为 jj 时,数组 nums1nums1nums2nums2 的异或值之和的最小值。初始时 f[0][0]=0f[0][0]=0,其余 f[i][j]=+f[i][j]=+\infty

我们可以枚举 nums1nums1 的第 ii 个数 xx,然后在 [0,2n)[0,2^n) 的范围内枚举状态 jj,转移方程为 f[i][j]=min(f[i][j],f[i1][j2k]+(xnums2[k]))f[i][j]=\min(f[i][j],f[i-1][j\oplus 2^k]+(x\oplus nums2[k])),其中 kkjj 的二进制表示中的某个 11 所在的位置。

最后答案为 f[n][2n1]f[n][2^n-1]

时间复杂度 O(n2×2n)O(n^2 \times 2^n),空间复杂度 O(n×2n)O(n \times 2^n)。其中 nn 是数组的长度。

我们注意到,状态 f[i][j]f[i][j] 只与 f[i1][j2k]f[i-1][j\oplus 2^k] 有关,因此我们去掉第一维,将空间复杂度优化到 O(2n)O(2^n)

1
2
3
4
5
6
7
8
9
10
11
12
class Solution:
    def minimumXORSum(self, nums1: List[int], nums2: List[int]) -> int:
        n = len(nums2)
        f = [[inf] * (1 << n) for _ in range(n + 1)]
        f[0][0] = 0
        for i, x in enumerate(nums1, 1):
            for j in range(1 << n):
                for k in range(n):
                    if j >> k & 1:
                        f[i][j] = min(f[i][j], f[i - 1][j ^ (1 << k)] + (x ^ nums2[k]))
        return f[-1][-1]
speed

复杂度分析

指标
时间Depends on the final approach
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    Check if the candidate understands the concept of dynamic programming with bitmasking.

  • question_mark

    Look for a candidate's ability to handle small n values efficiently using DP.

  • question_mark

    Assess whether the candidate can explain the trade-off of using DP over brute force permutations.

warning

常见陷阱

外企场景
  • error

    Forgetting to properly manage the bitmask when updating the DP state.

  • error

    Overlooking the fact that bitmasking can reduce time complexity exponentially, so brute-forcing is inefficient.

  • error

    Incorrectly handling the transition between different DP states, leading to wrong XOR sums.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Consider alternative bitmask approaches for larger values of n (though the complexity may not scale well).

  • arrow_right_alt

    Explore greedy algorithms or heuristics for larger inputs, but note the trade-offs in terms of optimality.

  • arrow_right_alt

    Optimize for space by reducing the size of the DP table when dealing with sparse subsets.

help

常见问题

外企场景

两个数组最小的异或值之和题解:状态·转移·动态规划 | LeetCode #1879 困难