[LeetCode] 1775. Equal Sum Arrays With Minimum Number of Operations
You are given two arrays of integers nums1
and nums2
, possibly of different lengths. The values in the arrays are between 1
and 6
, inclusive.
In one operation, you can change any integer's value in any of the arrays to any value between 1
and 6
, inclusive.
Return the minimum number of operations required to make the sum of values in nums1
equal to the sum of values in nums2
. Return -1
if it is not possible to make the sum of the two arrays equal.
Example 1:
Input: nums1 = [1,2,3,4,5,6], nums2 = [1,1,2,2,2,2] Output: 3 Explanation: You can make the sums of nums1 and nums2 equal with 3 operations. All indices are 0-indexed. - Change nums2[0] to 6. nums1 = [1,2,3,4,5,6], nums2 = [6,1,2,2,2,2]. - Change nums1[5] to 1. nums1 = [1,2,3,4,5,1], nums2 = [6,1,2,2,2,2]. - Change nums1[2] to 2. nums1 = [1,2,2,4,5,1], nums2 = [6,1,2,2,2,2].
Example 2:
Input: nums1 = [1,1,1,1,1,1,1], nums2 = [6] Output: -1 Explanation: There is no way to decrease the sum of nums1 or to increase the sum of nums2 to make them equal.
Example 3:
Input: nums1 = [6,6], nums2 = [1] Output: 3 Explanation: You can make the sums of nums1 and nums2 equal with 3 operations. All indices are 0-indexed. - Change nums1[0] to 2. nums1 = [2,6], nums2 = [1]. - Change nums1[1] to 2. nums1 = [2,2], nums2 = [1]. - Change nums2[0] to 4. nums1 = [2,2], nums2 = [4].
Constraints:
1 <= nums1.length, nums2.length <= 105
1 <= nums1[i], nums2[i] <= 6
通过最少操作次数使数组的和相等。
给你两个长度可能不等的整数数组 nums1 和 nums2 。两个数组中的所有值都在 1 到 6 之间(包含 1 和 6)。
每次操作中,你可以选择 任意 数组中的任意一个整数,将它变成 1 到 6 之间 任意 的值(包含 1 和 6)。
请你返回使 nums1 中所有数的和与 nums2 中所有数的和相等的最少操作次数。如果无法使两个数组的和相等,请返回 -1 。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/equal-sum-arrays-with-minimum-number-of-operations
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这道题的思路有不止一种,这里我先提供一种贪心的思路。
题目请你做若干次操作,使得 nums1 和 nums2 中所有数的和相等,我的思路是既然是让两个数组的 sum 相等(sum1 == sum2),那么如果我有办法让两个数组的元素尽可能多地相同,也能达到相同的目的。所以这里我首先算一下两个数组各自的 sum。这里有一个 corner case 需要排除,如果其中一个数组的长度大于另一个数组的长度 * 6,那么就一定找不到可行解,比如例子二,因为 nums[i] 的范围只能是在 1 - 6 之间。
计算完两个数组的和之后,我再对两个数组分别排序,同时我定义两个指针,一个从 nums1 的左侧开始走,一个从 nums2 的右侧开始走。只要 sum1 != sum2,我就需要检查看看如何操作收益更大。收益更大的意思是因为每次改动都算一次操作,所以我要尽可能把一个很小的数字改大,或者把一个很大的数字改小。换到这道题的语境里,如果 sum1 < sum2,同时 nums1 里的某个数字和 6 的差值 > nums2 里的某个数字和 1 的差值,我就改 nums1 里的数字,否则我就改 nums2 里的数字。
时间O(nlogn)
空间O(1)
Java实现
1 class Solution { 2 public int minOperations(int[] nums1, int[] nums2) { 3 // corner case 4 if (nums1.length * 6 < nums2.length || nums1.length > 6 * nums2.length) { 5 return -1; 6 } 7 8 // normal case 9 int sum1 = 0; 10 int sum2 = 0; 11 for (int num : nums1) { 12 sum1 += num; 13 } 14 for (int num : nums2) { 15 sum2 += num; 16 } 17 // 把sum较小的放在前面 18 if (sum1 > sum2) { 19 return minOperations(nums2, nums1); 20 } 21 22 Arrays.sort(nums1); 23 Arrays.sort(nums2); 24 int i = 0; 25 int j = nums2.length - 1; 26 int count = 0; 27 while (sum2 > sum1) { 28 if (j < 0 || i < nums1.length && 6 - nums1[i] > nums2[j] - 1) { 29 sum1 += 6 - nums1[i++]; 30 } else { 31 sum2 -= nums2[j--] - 1; 32 } 33 count++; 34 } 35 return count; 36 } 37 }