[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 }

 

LeetCode 题目总结

posted @ 2022-12-07 07:33  CNoodle  阅读(69)  评论(0编辑  收藏  举报