LeetCode 1775. 通过最少操作次数使数组的和相等
Posted Tisfy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 1775. 通过最少操作次数使数组的和相等相关的知识,希望对你有一定的参考价值。
【LetMeFly】1775.通过最少操作次数使数组的和相等
力扣题目链接:https://leetcode.cn/problems/equal-sum-arrays-with-minimum-number-of-operations/
给你两个长度可能不等的整数数组 nums1
和 nums2
。两个数组中的所有值都在 1
到 6
之间(包含 1
和 6
)。
每次操作中,你可以选择 任意 数组中的任意一个整数,将它变成 1
到 6
之间 任意 的值(包含 1
和 6
)。
请你返回使 nums1
中所有数的和与 nums2
中所有数的和相等的最少操作次数。如果无法使两个数组的和相等,请返回 -1
。
示例 1:
输入:nums1 = [1,2,3,4,5,6], nums2 = [1,1,2,2,2,2] 输出:3 解释:你可以通过 3 次操作使 nums1 中所有数的和与 nums2 中所有数的和相等。以下数组下标都从 0 开始。 - 将 nums2[0] 变为 6 。 nums1 = [1,2,3,4,5,6], nums2 = [6,1,2,2,2,2] 。 - 将 nums1[5] 变为 1 。 nums1 = [1,2,3,4,5,1], nums2 = [6,1,2,2,2,2] 。 - 将 nums1[2] 变为 2 。 nums1 = [1,2,2,4,5,1], nums2 = [6,1,2,2,2,2] 。
示例 2:
输入:nums1 = [1,1,1,1,1,1,1], nums2 = [6] 输出:-1 解释:没有办法减少 nums1 的和或者增加 nums2 的和使二者相等。
示例 3:
输入:nums1 = [6,6], nums2 = [1] 输出:3 解释:你可以通过 3 次操作使 nums1 中所有数的和与 nums2 中所有数的和相等。以下数组下标都从 0 开始。 - 将 nums1[0] 变为 2 。 nums1 = [2,6], nums2 = [1] 。 - 将 nums1[1] 变为 2 。 nums1 = [2,2], nums2 = [1] 。 - 将 nums2[0] 变为 4 。 nums1 = [2,2], nums2 = [4] 。
提示:
1 <= nums1.length, nums2.length <= 105
1 <= nums1[i], nums2[i] <= 6
方法一:贪心 + 计数
两个数组中的元素的初始和可能不同。为了方便,我们假设第一个数组的元素和小于第二个数组(不是的话交换两个数组的地址即可)
那么,我们的任务就是,将第一个数组中的元素变大,或者将第二个数组中的元素减小,使得两个数组中的元素和相等。
因为数字的合法范围是 1 1 1到 6 6 6,因此,第一个数组中,我们尽量让小的元素优先变成 6 6 6,这样所带来的“和的增加”最多。
同理,第二个数组中,我们尽量让大的元素变成 1 1 1,这样所带来的“和的减少”最多。
因此,我们可以预处理一遍两个数组,计算出两个数组中“和的差值”,并统计两个数组中1到6的元素的个数
然后,我们将第一个数组中的“1”变成“6”,同时将第二个数组中的“6”变成“1”,直到“没有元素可变”或“差值小于等于0”
接着,我们将第一个数组中的“2”变成“6”,同时将第二个数组中的“5”变成“1”,直到“没有元素可变”或“差值小于等于0”
…
这样,我们每次修改元素,都是“尽最大努力”地减小了两个数组中的差值,这样就能保证每次更改能“尽大可能”地缩小差值
这就是贪心
其实不难发现,将第一个数组中的“1”变成“6”和将第二个数组中的“6”变成“1”所带来的结果是等价的,因此,为了方便,我们可以直接将第二个数组中的“6”和第一个数组中的“1”统计到一起。
- 时间复杂度 O ( l e n ( n u m s 1 ) + l e n ( n u m s 2 ) + C ) O(len(nums1) + len(nums2) + C) O(len(nums1)+len(nums2)+C),其中 C C C是数组中元素的合法范围的大小,即 C = 6 C=6 C=6
- 空间复杂度 O ( C ) O(C) O(C)
AC代码
C++
class Solution
public:
int minOperations(vector<int>& nums1, vector<int>& nums2)
int s1 = accumulate(nums1.begin(), nums1.end(), 0);
int s2 = accumulate(nums2.begin(), nums2.end(), 0);
if (s1 > s2)
swap(nums1, nums2);
int times[6] = 0;
for (int& t : nums1)
times[t - 1]++;
for (int& t : nums2)
times[6 - t]++;
int ans = 0;
int loc = 0;
int diff = abs(s2 - s1);
while (diff)
int perChange = 6 - loc - 1;
if (!perChange)
break;
int maxChange = times[loc] * perChange;
int realChange = min(maxChange, diff);
diff -= realChange;
int changeTimes = realChange / perChange + (realChange % perChange != 0);
ans += changeTimes;
loc++;
return diff ? -1 : ans;
;
同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/128216782
以上是关于LeetCode 1775. 通过最少操作次数使数组的和相等的主要内容,如果未能解决你的问题,请参考以下文章
力扣LeetCode-1713. 得到子序列的最少操作次数-题解-最长递增子序列
力扣LeetCode-1713. 得到子序列的最少操作次数-题解-最长递增子序列