描述:
给你两个下标从 0 开始的整数数组 nums1
和 nums2
,这两个数组的长度都是 n
。
你可以执行一系列 操作(可能不执行)。
在每次操作中,你可以选择一个在范围 [0, n - 1]
内的下标 i
,并交换 nums1[i]
和 nums2[i]
的值。
你的任务是找到满足以下条件所需的 最小 操作次数:
nums1[n - 1]
等于nums1
中所有元素的 最大值 ,即nums1[n - 1] = max(nums1[0], nums1[1], ..., nums1[n - 1])
。nums2[n - 1]
等于nums2
中所有元素的 最大值 ,即nums2[n - 1] = max(nums2[0], nums2[1], ..., nums2[n - 1])
。
以整数形式,表示并返回满足上述 全部 条件所需的 最小 操作次数,如果无法同时满足两个条件,则返回 -1
。
示例 1:
输入:nums1 = [1,2,7],nums2 = [4,5,3] 输出:1 解释:在这个示例中,可以选择下标 i = 2 执行一次操作。 交换 nums1[2] 和 nums2[2] 的值,nums1 变为 [1,2,3] ,nums2 变为 [4,5,7] 。 同时满足两个条件。 可以证明,需要执行的最小操作次数为 1 。 因此,答案是 1 。
示例 2:
输入:nums1 = [2,3,4,5,9],nums2 = [8,8,4,4,4] 输出:2 解释:在这个示例中,可以执行以下操作: 首先,选择下标 i = 4 执行操作。 交换 nums1[4] 和 nums2[4] 的值,nums1 变为 [2,3,4,5,4] ,nums2 变为 [8,8,4,4,9] 。 然后,选择下标 i = 3 执行操作。 交换 nums1[3] 和 nums2[3] 的值,nums1 变为 [2,3,4,4,4] ,nums2 变为 [8,8,4,5,9] 。 同时满足两个条件。 可以证明,需要执行的最小操作次数为 2 。 因此,答案是 2 。
示例 3:
输入:nums1 = [1,5,4],nums2 = [2,5,3] 输出:-1 解释:在这个示例中,无法同时满足两个条件。 因此,答案是 -1 。
提示:
1 <= n == nums1.length == nums2.length <= 1000
1 <= nums1[i] <= 109
1 <= nums2[i] <= 109
注意:题意限定了两个数组nums1和nums2的元素交换只能发生在相同下标之间的交换。
题目要求nums1[n - 1]和nums2[n - 1]分别是nums1和nums2的最大值mx1、mx2(n为数组的大小),但交换只能发生在相同的下标之间,因此想要找到满足条件的情况,只需要分别讨论下标 n - 1 发生交换和 n - 1 不发生交换的两种情形,枚举0 ~ n - 2 如果不满足nums1[n - 1]和nums2[n - 1],那么就进行交换。假设当前枚举到i,不满足nums1[n - 1]和nums2[n - 1],设x = nums1[i],y = nums2[i],若(x > mx1 || y > mx2) && (x > mx2 || y > mx1),说明交换后还是不能满足最末尾为最大值,直接返回n + 1。
代码如下:
class Solution {
public:
int minOperations(vector<int>& nums1, vector<int>& nums2) {
// 只有两种情况
// 最后一对数交换了
// 最后一对数没有交换
int n = nums1.size();
auto op = [&](int last1, int last2){
int ans = 0;
for(int i = 0; i < n - 1; i++){
int x = nums1[i], y = nums2[i];
if(x > last1 || y > last2){
if(x > last2 || y > last1){
return n + 1;
}
ans++;
}
}
return ans;
};
int ans = min(op(nums1[n - 1], nums2[n - 1]),
1 + op(nums2[n - 1], nums1[n - 1]));
return ans <= n ? ans : -1;
}
};