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] 。
提示:
1 <= nums1.length, nums2.length <= 105
1 <= nums1[i], nums2[i] <= 6
原站题解
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]