持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情
力扣——2449. 使数组相似的最少操作次数
2449. 使数组相似的最少操作次数
给你两个正整数数组 nums 和 target ,两个数组长度相等。
在一次操作中,你可以选择两个 不同 的下标 i 和 j ,其中 0 <= i, j < nums.length ,并且:
令 nums[i] = nums[i] + 2 且 令 nums[j] = nums[j] - 2 。 如果两个数组中每个元素出现的频率相等,我们称两个数组是 相似 的。
请你返回将 nums 变得与 target 相似的最少操作次数。测试数据保证 nums 一定能变得与 target 相似。
示例 1:
输入:nums = [8,12,6], target = [2,14,10]
输出:2
解释:可以用两步操作将 nums 变得与 target 相似:
- 选择 i = 0 和 j = 2 ,nums = [10,12,4] 。
- 选择 i = 1 和 j = 2 ,nums = [10,14,2] 。
2 次操作是最少需要的操作次数。
提示:
- n == nums.length == target.length
- 1 <= n <= 105
- 1 <= nums[i], target[i] <= 106
- nums 一定可以变得与 target 相似。
问题解析
脑筋急转弯。
我们可以知道,因为运算是+2和-2。所以target中的奇数元素一定只能从nums中的奇数元素得到,偶数元素同理。
我们还知道,对于把数组变得和另一个数组相同的情况,那么在两边数组有序的情况下把ai变成bi一定是操作数最小的解法。
那么我们可以把两边数组的元素根据奇偶性分开后并排序。
因为题目保证了nums一定可以变得与target相似,所以不管+2操作还是-2操作,它们的操作数一定是一样的。
所以我们也不用管对于当前元素是+2操作还是-2操作,我们直接计算他们差值的绝对值,除于2后就是这个数的操作次数。我们计算所有数的总操作数res。
因为我们一次操作可以同时进行+2和-2的操作,所以总操作数res还要除于2,才是我们的结果。
AC代码
class Solution {
public:
typedef long long ll;
long long makeSimilar(vector<int>& nums, vector<int>& target) {
vector<ll>ji,ou,ji2,ou2;
for(auto&i:nums)
{
if(i%2==1)ji.push_back(i);
else ou.push_back(i);
}
for(auto&i:target)
{
if(i%2==1)ji2.push_back(i);
else ou2.push_back(i);
}
sort(ji.begin(),ji.end());
sort(ji2.begin(),ji2.end());
sort(ou.begin(),ou.end());
sort(ou2.begin(),ou2.end());
ll n=ji.size(),m=ou.size(),res=0;
for(int i=0;i<n;i++)
{
res+=(abs(ji[i]-ji2[i]))/2;
}
for(int i=0;i<m;i++)
{
res+=(abs(ou[i]-ou2[i]))/2;
}
return res/2;
}
};