1、题干
给你两个长度可能不等的整数数组 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 <= 1051 <= nums1[i], nums2[i] <= 6
Problem: 1775. 通过最少操作次数使数组的和相等
2、思路
题目要求使数组的和相等的最少操作次数,可以使用贪心算法。假设 nums1 的和较小,升序地将 nums1 中的数尽量变大(最大为 6),降序地将 nums2 中的数尽量变小(最小为 1),直到两个数组的和相等。
操作时需要同时处理 nums1 中的数 n 和 nums2 中的数 7-n。
3、Code
function minOperations(nums1: number[], nums2: number[]): number {
    const n1 = nums1.length, n2 = nums2.length;
    if (n1 < n2 && 6 * n1 < n2 || (n2 < n1 && 6 * n2 < n1)) return -1;
    let sum1 = nums1.reduce((a, c) => a + c, 0);
    let sum2 = nums2.reduce((a, c) => a + c, 0);
    if (sum1 === sum2) return 0;
    if (sum1 > sum2) [sum1, sum2, nums1, nums2] = [sum2, sum1, nums2, nums1];
    const diffList = new Array(6).fill(0);
    for (let i = 0; i < Math.max(n1, n2); i++) {
        if (nums1[i]) diffList[6 - nums1[i]] += 1;
        if (nums2[i]) diffList[nums2[i] - 1] += 1;
    }
    let ans = 0, diff = sum2 - sum1;
    for (let d = 5; d > 0 && diff > 0; d--) {
        const u = Math.min(diffList[d], Math.ceil(diff / d));
        diff -= d * u;
        ans += u;
    }
    return ans;
};
4、复杂度
- 时间复杂度:
 - 空间复杂度:
 
5、执行结果
