leetcode 1775通过最少操作次数使数组和相等

来源:力扣(LeetCode)–NO.1775
链接:https://leetcode.cn/problems/equal-sum-arrays-with-minimum-number-of-operations

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

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

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

  • 1 <= nums1.length, nums2.length <= 105
  • 1 <= nums1[i], nums2[i] <= 6
    在这里插入图片描述
// 🎈本题使用贪心 + hashmap
class Solution {
public:
    /*
    help函数:辅助函数,用于增加h1所代表的数组sum,减小h2所代表的数组sum
    目标:缩小diff直到其大于等于0(大于0也一定能缩小再等于零)
    	**在本题中,仅有(len1*6 < len2 || len2*6 < len1)这种情况返回-1**
    */
    int help(vector<int> h1, vector<int> h2, diff) {
        vector<int>contribute; // 计算每个数的贡献度
        // 贡献度的目的是加起来能够抵消diff
        // 大的减小,小的增加,计算贡献度
        
        // 哈希表 👇
        
        for(int i = 1; i < 7; ++i) {
            h1[6-i] = h[i];  
            h2[i-1] = h[i];
        }
        int count = 0; // 定义计数器
        
        // 贪心思想 👇
        
        for(int i = 5; i && diff >= 0; --i){// 贡献度由高到低进行遍历
        	int t = min((diff+i-1)/i, h[i]); 
            //⭐ diff+i-1的作用是--- 使diff/i **向上取整**
            count += t;
            diff -= t*i;  // 减去贡献度
        }
    }
    
    int minOperations(vector<int>& nums1, vector<int>& nums2) {
		vector<int>cnt1;
        vector<int>cnt2;
        int diff = 0;
        int len1 = nums1.size();
        int len2 = nums2.size();
        // ⭐**在本题中,仅有(len1*6 < len2 || len2*6 < len1)这种情况返回-1**
        if(len1*6 < len2 || len2*6 < len1)	return -1;
        for(int i = 0; i < len1; ++i) {
            diff += nums1[i];
            ++cnt1[nums1[i]];
        }
        for(int i = 0; i < len2; ++i) {
            diff -= nums2[i];
            ++cnt2[nums2[i]];
        }
        if(!diff)	return 0;
        
        // diff的正负并不重要 
        // ⭐本质是:增加nums1(nums2),减小nums2(nums1)以缩小diff
        
        // diff>0 --> sum1 > sum2
        if(diff > 0)	return help(cnt2, cnt1, diff);
        // diff<0 --> sum1 < sum2
        return help(cnt1, cnt2, -diff); // 取diff的绝对值
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值