给你两个整数数组 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
相等。
解题思路:首先根据题目就能够知道先给我们两个测试数组num1和num2,num1必定比num2多两个元素,我们只需要找到能使num1删除两个元素后与num2最小的差x,最终达到num1加上x等于num2的结果。
1. 第一步便是要给num1和num2从小到大排序了,方便后序遍历找到x,这里我们用快排qsort来操作。
2. 把两个数组遍历后我们设置一个minX来保存最终结果,先初始化为无穷大,然后一一假设,用一个for循环来假设x的值,如果符合chick函数,则保存到minX里面,否则继续循环。
3. 注意这里的for循环条件一定是i<3,原因是最多只能删除两个num1元素,check函数来验证当前x是否符合条件,不符合就继续循环,直到删除了两个元素为止。
程序如下:
// 用于比较的函数(递增排序)
int compare(const void *a, const void *b) {
return (*(int *)a - *(int *)b);
}
// 检查函数,验证当前的 x 是否能使剩余元素匹配
int check(int* nums1, int nums1Size, int* nums2, int nums2Size, int x, int ans, int j) {
for (int i = 0; i < nums2Size; i++) {
// 寻找匹配的元素
while (nums2[i] != nums1[j] + x) {
j++; // 移动到 nums1 中的下一个元素
ans--; // 减少剩余可移除的元素数
if (ans < 0) return 0; // 如果移除的元素数超出限制,则返回 false
}
j++; // 继续检查下一个 nums2 的元素
}
return 1; // 成功匹配,返回 true
}
// 主函数,寻找最小的 x
int minimumAddedInteger(int* nums1, int nums1Size, int* nums2, int nums2Size) {
// 对两个数组进行排序
qsort(nums1, nums1Size, sizeof(int), compare);
qsort(nums2, nums2Size, sizeof(int), compare);
int minX = INT_MAX; // 初始化最小 x 为无穷大
// 尝试从 nums1 中移除最多两个元素
for (int i = 0; i < 3; i++) {
int x = nums2[0] - nums1[i]; // 假设当前 x
// 检查当前 x 是否可行,且比之前的最小 x 更小
if (check(nums1, nums1Size, nums2, nums2Size, x, 2 - i, i)) {
if (x < minX) minX = x; // 更新最小 x
}
}
return minX; // 返回最终的最小 x
}
提交结果:
题目引用:https://leetcode.cn/problems/find-the-integer-added-to-array-ii/