1775. 通过最少操作次数使数组的和相等
思路:哈希表+贪心。时间复杂度0(n)。
1、先找到无法使两个数组和相等的情况
2、然后计算出两个数组和之间的差值d
3、对于和数大的数组,那肯定是要向下减少;和数小的数组,就是要向上增加
4、那么我们统计出两个数组里每个元素的最大变化范围(0~5)
5、然后5开始递减,逐步缩小差值d
细节看注释
class Solution {
public:
int minOperations(vector<int>& nums1, vector<int>& nums2) {
int n=nums1.size(),m=nums2.size();
//第一种情况:第一个数组都是6、第二个数组都是1,第一个数组和还是小于第二个数组和
//第二种情况:第一个数组都是1、第二个数组都是6,第一个数组和还是大于第二个数组和
if(n*6<m||n>6*m) return -1;
//用来记录两个数组元素可变化的最大范围的总次数
int a[10];
memset(a,0,sizeof a);//记得初始化为0,呜呜呜
//统计两数组之差
int d=accumulate(nums1.begin(),nums1.end(),0)-accumulate(nums2.begin(),nums2.end(),0);
//保持第一个数组之和是大的
if(d<0){
d=-1*d;
swap(nums1,nums2);
swap(n,m);
}
//和数大的,那就减少
for(int i=0;i<n;i++){
a[nums1[i]-1]++;
}
//和数小的,那就增大
for(int i=0;i<m;i++){
a[6-nums2[i]]++;
}
int ans=0;
for(int i=5;i>0;i--){
//说明这一次是可以消灭差距的
if(i*a[i]>=d){
//这里是向上取整,虽然会有多的部分,但是多出来的一个是可以把变化范围往下调的呀
ans+=(d+i-1)/i;
break;
}
ans+=a[i];
d-=a[i]*i;
}
return ans;
}
};