图解LeetCode——1775. 通过最少操作次数使数组的和相等(难度:中等)
创始人
2024-03-23 11:55:14

一、题目

给你两个长度可能不等的整数数组 nums1 和 nums2 。两个数组中的所有值都在 1 到 6 之间(包含 1 和 6)。

每次操作中,你可以选择 任意 数组中的任意一个整数,将它变成 1 到 6 之间 任意 的值(包含 1 和 6)。

请你返回使 nums1 中所有数的和与 nums2 中所有数的和相等的最少操作次数。如果无法使两个数组的和相等,请返回 -1

二、示例

2.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.2> 示例 2:

【输入】nums1 = [1,1,1,1,1,1,1], nums2 = [6]
【输出】-1
【解释】没有办法减少 nums1 的和或者增加 nums2 的和使二者相等。

2.3> 示例 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 <= 10^5
  • 1 <= nums1[i], nums2[i] <= 6

三、解题思路

首先,根据题意,我们需要计算出数组nums1nums2之间,最小的操作次数,使得nums1的总和:sum(nums1)与nums2的总和:sum(nums2)两个值相等。那么我们可以根据如下4个步骤来解决这个问题:

步骤1】分别计算sum(nums1)sum(nums2)的值,确定两个数组加和的差值diff,以及sum(nums1)sum(nums2)之间的大小关系

 【步骤2】将总和较小的数组赋值为int[] smaller,将总和较大的数组赋值为int[] bigger

对于smaller数组中的每个值,我们要执行变大操作,其中:由于最大值是6,所以每个元素s变大的最大跨度是:6 - s
对于bigger数组中的每个值,我们要执行变小操作,其中:由于最小值是1,所以每个元素b变大的最大跨度是:b - 1

 【步骤3】创建一个用于存储跨度&出现次数的数组int[] range(也可以采用Map结构),其中:下标index表示跨度值range[index]表示该跨度值出现的次数。由于题目中指出,nums1和nums2中元素的值的范围是[1, 6],所以,对应的跨度值就是[0, 5]。为了便于画图,图中采用Map结构表示:

 【步骤4】由于要求计算出最小操作次数,所以我们需要从range数组末尾开始遍历执行对比操作,以上面图中的例子做演示,diff=11range=[1,1,1,1,5,3]

第1次操作】因为差值diff > 跨度5,所以差值diff变为6(11减5),range[5]的出现次数变为2(3减1);
第2次操作】因为差值diff > 跨度5,所以差值diff变为1(6减5),range[5]的出现次数变为1(2减1);
第3次操作】因为差值diff <= 跨度5,满足题解,返回最少操作次数为:3

四、代码实现

class Solution {public int minOperations(int[] nums1, int[] nums2) {int result = 0, l1 = nums1.length, l2 = nums2.length, sum1 = 0, sum2 = 0, diff;if (6 * l1 < l2 || 6 * l2 < l1) return -1; // 无法使两个数组的和相等,返回-1for (int n1 : nums1) sum1 += n1;for (int n2 : nums2) sum2 += n2;if ((diff = Math.abs(sum1 - sum2)) == 0) return 0; // 如果两个数组和相等,则不需要操作,返回0int[] range = calculate(nums1, nums2, sum1, sum2);for (int i = 5; i >= 0; i--) { // 从最大的差值开始对比while (range[i] > 0) { // 如果差值range[i]出现的次数不为0result++; // 操作次数加1if (i >= diff) return result; // 如果差值大于等于diff,则操作结束,返回操作数resultrange[i]--; // 差值range[i]的出现次数减1diff -= i; // 更新diff值}}return -1;}// 计算每个差值(1~5)出现的次数private int[] calculate(int[] nums1, int[] nums2, int sum1, int sum2) {int[] bigger = (sum1 < sum2) ? nums2 : nums1;int[] smaller = (sum1 < sum2) ? nums1 : nums2;int[] range = new int[6]; // index:差值  range[index]:该差值出现的次数for (int s : smaller) ++range[6 - s]; // 对于总数较小的数组,要执行增加操作,由于理论上最大值是6,所以最大可以增加"6-s"个数值for (int b : bigger) ++range[b - 1]; // 对于总数较大的数组,要执行减法操作,由于理论上最小值是1,所以最大可以减少"b-1"个数值return range;}
}

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。

更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...