题目

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

解题思路

设定nums1元素和恒小于nums2元素和

  1. 判断nums1或者nums2所有元素变成6,另一个数组所有元素变成1,若小于则输出-1
  2. 求出nums1的和 - nums2的和 命名为d
  3. d < 0则说明nums2和 < nums1和我们要将d改为正数同时交换nums1和nums2
  4. 统计nums1nums2中每个元素的最大变化量
    • nums1[i]最大能变成6,最大变化量为6 - nums1[i]
    • nums2[i]最小能变成1,最大变化量为nums2[i] - 1
  5. 从最大元素遍历到最小元素
    1. 可以让d为0,次数累加同时返回答案
    2. 累加次数

代码

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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)
if d < 0:
d = -d
nums1, nums2 = nums2, nums1
ans = 0
cnt = Counter(6 - x for x in nums1) + Counter(6 - x for x in nums2)
for i in range(5, 0, -1):
if i * cnt[i] >= d:
return ans + (d + i - 1) // i
ans += cnt[i]
d -= i * cnt[i]

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
public:
int minOperations(vector<int>& nums1, vector<int>& nums2) {
if (nums1.size() * 6 < nums2.size() || nums2.size() * 6 < nums1.size()){
return -1;
}
int d = sumVector_int(nums2) - sumVector_int(nums1);
if (d < 0){
d = -d;
vector<int> t;
t = nums2;
nums2 = nums1;
nums1 = t;
}
int cnt[6]{};
for (int x: nums1) cnt[6 - x]++;
for (int x: nums2) cnt[x - 1]++;
int ans = 0;
for (int i = 5; i > -1; i--){
if (i * cnt[i] >= d){
return ans + (d + i - 1) / i;
}
ans += cnt[i];
d -= i * cnt[i];
}
return 0;
}
int sumVector_int(vector<int>& nums){
int n = nums.size();
int result = 0;
for (auto x: nums){
result += x;
}
return result;
}
};

GO

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
func minOperations(nums1 []int, nums2 []int) int {
if len(nums1) * 6 < len(nums2) || len(nums2) * 6 < len(nums1){
return -1
}
d := SumNums(nums2) - SumNums(nums1)
if d < 0{
d = -d
nums1, nums2 = nums2, nums1
}
//----------------------
// 记录最大变化量
cnt := make([]int, 6, 6)
for _, x := range nums1{
cnt[6 - x]++
}
for _, x := range nums2{
cnt[x - 1]++
}
//-----------------------
ans := 0
for i := 5; i > -1; i--{
if i * cnt[i] >= d{
return ans + (d + i - 1) / i
}
ans += cnt[i]
d -= i * cnt[i]
}
return ans
}

//----------------------------
// 数组元素和
func SumNums(nums []int) int{
result := 0
for _, x := range nums{
result += x
}
return result
}
//----------------------------