Leetcode1775.通过最少操作次数使数组的和相等

题目描述

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

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

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

解题思路

【步骤1】求出nums1和nums2的和分别为 sum1,sum2。nums1和nums2差值为diff。注意:sum1>sum2时,diff传参为diff;sum1<sum2时,diff传参为-diff

【步骤2】元素范围为[1,6],可变化范围为[0,5],可变大6-x,可变小x-1。

【步骤3】构造哈希表,分别存不同跨度值出现次数。

【步骤4】由大到小遍历哈希表,每次diff减去跨度值*元素个数,直到diff<=0返回ans。

class Solution {
public:
    int  help(vector<int>&nums1,vector<int>&nums2,int diff){
        vector<int> mp(6, 0);//数组相当于哈希表,0~5分别存对应贡献值可以修改的元素数量
        int ans=0;
        for (int x : nums1) mp[x - 1]++; //对于每个数可以减少的量
        for (int x : nums2) mp[6 - x]++; //对于每个数可以增加的量 
        for (int i = 5; i >= 1 && diff > 0; i--) {
            int cnt = min(mp[i], (diff + i - 1) / i); //最少需要的个数 +(i- 1)为了向上取整。
            ans += cnt;
            diff -= cnt * i; //减去能够减少的最大值,若小于等等于0,代表已经使得两个数组相等
        }
        return ans;
    }
    int minOperations(vector<int>& nums1, vector<int>& nums2) {
        int n1 = nums1.size(), n2 = nums2.size(), ans = 0;
        if (n1 * 6 < n2 || n2 * 6 < n1) return -1;//即使n1或n2全部所有元素全部为6也小于n2或n1所有元素全部为1
        int sum1=0;
        int sum2=0;
        for(const int&q:nums1)//遍历nums1,求出sum1
        sum1+=q;
        for(const int&p:nums2)//遍历nums2,求出sum2
        sum2+=p;
        int diff=sum1-sum2;
        if(diff>0)
        return help(nums1,nums2,diff);
        else
        return help(nums2,nums1,-diff);//diff<0,应该传入相反数
    }
};

解题思路来自作者muse-77
链接:https://leetcode.cn/problems/equal-sum-arrays-with-minimum-number-of-operations/solution/zhua-wa-m-by-muse-77-f2zh/
来源:力扣(LeetCode)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值