- 标签:位运算、数组、动态规划、状态压缩
- 难度:困难
描述:给定两个整数数组
要求:将
说明:
-
两个数组的异或值之和:$(nums1[0] \oplus nums2[0]) + (nums1[1] \oplus nums2[1]) + ... + (nums1[n - 1] \oplus nums2[n - 1])$(下标从
$0$ 开始)。 - 举个例子,$[1, 2, 3]$ 和
$[3, 2, 1]$ 的异或值之和 等于$(1 \oplus 3) + (2 \oplus 2) + (3 \oplus 1) + (3 \oplus 1) = 2 + 0 + 2 = 4$ 。 -
$n == nums1.length$ 。 -
$n == nums2.length$ 。 -
$1 \le n \le 14$ 。 -
$0 \le nums1[i], nums2[i] \le 10^7$ 。
示例:
- 示例 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。
由于数组
同时因为两个数组长度
「状态压缩」指的是使用一个
如果二进制数
举个例子:
-
$nums2 = \lbrace 1, 2, 3, 4 \rbrace, state = (1001)_2$ ,表示选择了第$1$ 个元素和第$4$ 个元素,也就是$1$ 、$4$。 -
$nums2 = \lbrace 1, 2, 3, 4, 5, 6 \rbrace, state = (011010)_2$ ,表示选择了第$2$ 个元素、第$4$ 个元素、第$5$ 个元素,也就是$2$ 、$4$、$5$。
这样,我们就可以通过动态规划的方式来解决这道题。
按照数组
定义当前数组
则可以定义状态
对于当前状态
举个例子
即状态转移方程为:$dp[state] = min(dp[state], \quad dp[state \oplus (1 \text{ <}\text{< } i)] + (nums1[i] \oplus nums2[one\underline{\hspace{0.5em}}cnt - 1]))$,其中
- 既然是求最小值,不妨将所有状态初始为最大值。
- 未选择任何数时,异或值之和为
$0$ ,所以初始化$dp[0] = 0$ 。
根据我们之前定义的状态,$dp[state]$ 表示为:当前数组
class Solution:
def minimumXORSum(self, nums1: List[int], nums2: List[int]) -> int:
ans = float('inf')
size = len(nums1)
states = 1 << size
dp = [float('inf') for _ in range(states)]
dp[0] = 0
for state in range(states):
one_cnt = bin(state).count('1')
for i in range(size):
if (state >> i) & 1:
dp[state] = min(dp[state], dp[state ^ (1 << i)] + (nums1[i] ^ nums2[one_cnt - 1]))
return dp[states - 1]
-
时间复杂度:$O(2^n \times n)$,其中
$n$ 是数组$nums1$ 、$nums2$ 的长度。 - 空间复杂度:$O(2^n)$。