列表

详情


1775. 通过最少操作次数使数组的和相等

给你两个长度可能不等的整数数组 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] 。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int minOperations(vector<int>& nums1, vector<int>& nums2) { } };

python3 解法, 执行用时: 108 ms, 内存消耗: 19.1 MB, 提交时间: 2022-12-07 17:39:44

class Solution:
    def help(self, h1: List[int], h2: List[int], diff: int) -> int:
        h = [0] * 7
        for i in range(1, 7):
            h[6 - i] += h1[i]
            h[i - 1] += h2[i]
        res = 0
        for i in range(5, 0, -1):
            if diff <= 0: break
            t = min((diff + i - 1) // i, h[i])
            res += t
            diff -= t * i
        return res

    def minOperations(self, nums1: List[int], nums2: List[int]) -> int:
        n, m = len(nums1), len(nums2)
        if 6 * n < m or 6 * m < n:
            return -1
        cnt1 = [0] * 7
        cnt2 = [0] * 7
        diff = 0
        for i in nums1:
            cnt1[i] += 1
            diff += i
        for i in nums2:
            cnt2[i] += 1
            diff -= i
        if diff == 0:
            return 0
        if diff > 0:
            return self.help(cnt2, cnt1, diff)
        return self.help(cnt1, cnt2, -diff)

golang 解法, 执行用时: 156 ms, 内存消耗: 8.2 MB, 提交时间: 2022-12-07 17:39:17

func help(h1 [7]int, h2 [7]int, diff int) (res int) {
    h := [7]int{}
    for i := 1; i < 7; i++ {
        h[6-i] += h1[i]
        h[i-1] += h2[i]
    }
    for i := 5; i > 0 && diff > 0; i-- {
        t := min((diff+i-1)/i, h[i])
        res += t
        diff -= t * i
    }
    return res
}

func minOperations(nums1 []int, nums2 []int) (ans int) {
    n, m := len(nums1), len(nums2)
    if 6*n < m || 6*m < n {
        return -1
    }
    var cnt1, cnt2 [7]int
    diff := 0
    for _, i := range nums1 {
        cnt1[i]++
        diff += i
    }
    for _, i := range nums2 {
        cnt2[i]++
        diff -= i
    }
    if diff == 0 {
        return 0
    }
    if diff > 0 {
        return help(cnt2, cnt1, diff)
    }
    return help(cnt1, cnt2, -diff)
}

func min(a, b int) int {
    if a > b {
        return b
    }
    return a
}

javascript 解法, 执行用时: 88 ms, 内存消耗: 51.8 MB, 提交时间: 2022-12-07 17:39:04

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number}
 */
var minOperations = function(nums1, nums2) {
    const n = nums1.length, m = nums2.length;
    if (6 * n < m || 6 * m < n) {
        return -1;
    }
    const cnt1 = new Array(7).fill(0);
    const cnt2 = new Array(7).fill(0);
    let diff = 0;
    for (const i of nums1) {
        ++cnt1[i];
        diff += i;
    }
    for (const i of nums2) {
        ++cnt2[i];
        diff -= i;
    }
    if (diff === 0) {
        return 0;
    }
    if (diff > 0) {
        return help(cnt2, cnt1, diff);
    }
    return help(cnt1, cnt2, -diff);
}

const help = (h1, h2, diff) => {
    const h = new Array(7).fill(0);
    for (let i = 1; i < 7; ++i) {
        h[6 - i] += h1[i];
        h[i - 1] += h2[i];
    }
    let res = 0;
    for (let i = 5; i > 0 && diff > 0; --i) {
        let t = Math.min(Math.floor((diff + i - 1) / i), h[i]);
        res += t;
        diff -= t * i;
    }
    return res;
};

java 解法, 执行用时: 2 ms, 内存消耗: 49.8 MB, 提交时间: 2022-12-07 17:38:47

class Solution {
    public int minOperations(int[] nums1, int[] nums2) {
        int n = nums1.length, m = nums2.length;
        if (6 * n < m || 6 * m < n) {
            return -1;
        }
        int[] cnt1 = new int[7];
        int[] cnt2 = new int[7];
        int diff = 0;
        for (int i : nums1) {
            ++cnt1[i];
            diff += i;
        }
        for (int i : nums2) {
            ++cnt2[i];
            diff -= i;
        }
        if (diff == 0) {
            return 0;
        }
        if (diff > 0) {
            return help(cnt2, cnt1, diff);
        }
        return help(cnt1, cnt2, -diff);
    }

    public int help(int[] h1, int[] h2, int diff) {
        int[] h = new int[7];
        for (int i = 1; i < 7; ++i) {
            h[6 - i] += h1[i];
            h[i - 1] += h2[i];
        }
        int res = 0;
        for (int i = 5; i > 0 && diff > 0; --i) {
            int t = Math.min((diff + i - 1) / i, h[i]);
            res += t;
            diff -= t * i;
        }
        return res;
    }
}

java 解法, 执行用时: 2 ms, 内存消耗: 50.4 MB, 提交时间: 2022-12-07 17:38:09

class Solution {
    public int minOperations(int[] nums1, int[] nums2) {
        if (6 * nums1.length < nums2.length || 6 * nums2.length < nums1.length)
            return -1; // 优化
        // int d = Arrays.stream(nums2).sum() - Arrays.stream(nums1).sum();
        int d = 0; // 数组元素和的差,我们要让这个差变为 0
        for (int x : nums2) d += x;
        for (int x : nums1) d -= x;
        if (d < 0) {
            d = -d;
            int[] tmp = nums1;
            nums1 = nums2;
            nums2 = tmp; // 交换,统一让 nums1 的数变大,nums2 的数变小
        }
        int[] cnt = new int[6]; // 统计每个数的最大变化量
        for (int x : nums1) ++cnt[6 - x]; // nums1 的变成 6
        for (int x : nums2) ++cnt[x - 1]; // nums2 的变成 1
        for (int i = 5, ans = 0; ; --i) { // 从大到小枚举最大变化量 5 4 3 2 1
            if (i * cnt[i] >= d) // 可以让 d 变为 0
                return ans + (d + i - 1) / i;
            ans += cnt[i]; // 需要所有最大变化量为 i 的数
            d -= i * cnt[i];
        }
    }
}

golang 解法, 执行用时: 112 ms, 内存消耗: 8.7 MB, 提交时间: 2022-12-07 17:37:53

func minOperations(nums1, nums2 []int) (ans int) {
    if 6*len(nums1) < len(nums2) || 6*len(nums2) < len(nums1) {
        return -1 // 优化
    }
    d := 0 // 数组元素和的差,我们要让这个差变为 0
    for _, x := range nums2 { d += x }
    for _, x := range nums1 { d -= x }
    if d < 0 {
        d = -d
        nums1, nums2 = nums2, nums1 // 统一让 nums1 的数变大,nums2 的数变小
    }
    cnt := [6]int{} // 统计每个数的最大变化量
    for _, x := range nums1 { cnt[6-x]++ } // nums1 的变成 6
    for _, x := range nums2 { cnt[x-1]++ } // nums2 的变成 1
    for i := 5; ; i-- { // 从大到小枚举最大变化量 5 4 3 2 1
        if i*cnt[i] >= d { // 可以让 d 变为 0
            return ans + (d+i-1)/i
        }
        ans += cnt[i] // 需要所有最大变化量为 i 的数
        d -= i * cnt[i]
    }
}

python3 解法, 执行用时: 112 ms, 内存消耗: 19.2 MB, 提交时间: 2022-12-07 17:37:41

class Solution:
    def minOperations(self, nums1: List[int], nums2: List[int]) -> int:
        if 6 * len(nums1) < len(nums2) or 6 * len(nums2) < len(nums1):
            return -1  # 优化
        d = sum(nums2) - sum(nums1)  # 数组元素和的差,我们要让这个差变为 0
        if d < 0:
            d = -d
            nums1, nums2 = nums2, nums1  # 统一让 nums1 的数变大,nums2 的数变小
        ans = 0
        # 统计每个数的最大变化量(nums1 的变成 6,nums2 的变成 1)
        cnt = Counter(6 - x for x in nums1) + Counter(x - 1 for x in nums2)
        for i in range(5, 0, -1):  # 从大到小枚举最大变化量 5 4 3 2 1
            if i * cnt[i] >= d:  # 可以让 d 变为 0
                return ans + (d + i - 1) // i
            ans += cnt[i]  # 需要所有最大变化量为 i 的数
            d -= i * cnt[i]

上一题