1879. 两个数组最小的异或值之和Java
文章发布较早,内容可能过时,阅读注意甄别。
# 题目
给你两个整数数组 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
# 思路
double
# 解法
class Solution {
int N = 400;
double hi = 1e5, lo = 1e-5, fa = 0.90;
Random random = new Random(20210531);
void swap(int[] n, int a, int b) {
int c = n[a];
n[a] = n[b];
n[b] = c;
}
int calc() {
int res = 0;
for (int i = 0; i < n; i++) res += n1[i] ^ n2[i];
ans = Math.min(ans, res);
return res;
}
void sa() {
for (double t = hi; t > lo; t *= fa) {
int a = random.nextInt(n), b = random.nextInt(n);
int c = random.nextInt(n), d = random.nextInt(n);
int prev = calc();
swap(n1, a, b);
swap(n2, c, d);
int cur = calc();
int diff = cur - prev;
if (Math.log(diff / t) >= random.nextDouble()) {
swap(n1, a, b);
swap(n2, c, d);
}
}
}
int[] n1, n2;
int n;
int ans = Integer.MAX_VALUE;
public int minimumXORSum(int[] _n1, int[] _n2) {
n1 = _n1; n2 = _n2;
n = n1.length;
while (N-- > 0) sa();
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 总结
- 分析出几种情况,然后分别对各个情况实现