目录
3132. 找出与数组相加的整数 II
题目描述:
给你两个整数数组 nums1
和 nums2
。
从 nums1
中移除两个元素,并且所有其他元素都与变量 x
所表示的整数相加。如果 x
为负数,则表现为元素值的减少。
执行上述操作后,nums1
和 nums2
相等 。当两个数组中包含相同的整数,并且这些整数出现的频次相同时,两个数组 相等 。
返回能够实现数组相等的 最小 整数 x
。
示例 1:
输入:nums1 = [4,20,16,12,8], nums2 = [14,18,10]
输出:-2
解释:
移除 nums1
中下标为 [0,4]
的两个元素,并且每个元素与 -2
相加后,nums1
变为 [18,14,10]
,与 nums2
相等。
示例 2:
输入:nums1 = [3,5,5,3], nums2 = [7,7]
输出:2
解释:
移除 nums1
中下标为 [0,3]
的两个元素,并且每个元素与 2
相加后,nums1
变为 [7,7]
,与 nums2
相等。
提示:
3 <= nums1.length <= 200
nums2.length == nums1.length - 2
0 <= nums1[i], nums2[i] <= 1000
- 测试用例以这样的方式生成:存在一个整数
x
,nums1
中的每个元素都与x
相加后,再移除两个元素,nums1
可以与nums2
相等。
实现代码与解析:
排序 + 暴力
class Solution {
public static int minimumAddedInteger(int[] nums1, int[] nums2) {
Arrays.sort(nums1);
Arrays.sort(nums2);
int n = nums1.length;
int res = 0x3f3f3f3f;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int idx2 = 0;
int pre = 0x3f3f3f3f;
for (int idx1 = 0; idx1 < n; idx1++) {
if (idx1 == i || idx1 == j) {
continue;
} else {
if (pre == 0x3f3f3f3f) {
pre = nums2[idx2] - nums1[idx1];
} else {
if (nums2[idx2] - nums1[idx1] != pre) {
pre = 0x3f3f3f3f;
break;
}
}
idx2++;
}
}
res = Math.min(res, pre);
}
}
return res;
}
public static void main(String[] args) {
int[] nums1 = new int[]{4,20,16,12,8};
int[] nums2 = new int[]{14,18,10};
int i = minimumAddedInteger(nums1, nums2);
System.out.println(i);
}
}
原理思路:
数据范围很小,直接暴力循环两个指针,然后判断是否成立,获取最小结果即可。当然有点过于暴力了,可以简洁点写,用双指针。
双指针
class Solution {
public int minimumAddedInteger(int[] nums1, int[] nums2) {
int n = nums1.length;
int m = nums2.length;
Arrays.sort(nums1);
Arrays.sort(nums2);
int res = 0x3f3f3f3f;
for (int i = 0; i < 3; ++i) {
int x = nums2[0] - nums1[i];
int j = 0, k = 0, cnt = 0;
while (j < n && k < m) {
if (nums2[k] - nums1[j] != x) cnt++;
else {
k++;
}
j++;
}
if (cnt <= 2) {
res = Math.min(x, res);
}
}
return res;
}
}
原理思路:
因为必存在答案,最多三个之中必有一个最后留下,所以遍历三个num1元素,求出x,验证x是否正确,取最小值。