题目描述
给你两个集合,集合中的元素是没有重复的,现在有一个magic操作,从一个集合中把一个元素丢进另一个集合中,要求,magic操作后,两个集合的平均值都增加。注意:不能把一个集合取空,第二,不能把元素重复放入集合中。
请你求出最多可以进行多少次magic操作?
思路分析
此题就是典型的业务逻辑问题,需要仔细分析。
首先假设两个集合的平均值相同,那么,无论怎么拿放元素,都至少有一个集合平均值减少,一个增加,或者两个都不变,显然不行。
因此,两个集合的平均值不能相同。
既然要求magic之后两个集合的平均值都增加,那么,肯定被拿走的元素,要小于当前集合的平均值,才能使平均值增加,同时,该元素一定要大于要放入集合的平均值,才能使该集合平均值增加,因此,只能从平均值大的集合往平均值小的集合中拿,并且要保证在两个集合的平均值之间。
分析完什么情况下可以拿元素,那么,如果有多个元素在两个集合平均值之间,该如何选择?
题目需要求出最多可以进行多少次magic操作,因此,此时需要一个小贪心策略,当两个集合的平均值相同时,则magic操作就该停止了,因此,用贪心思想,我们应该尽可能的保持两个集合平均值的差值越大,则magic操作越多,因此,我们选择满足条件中最小的转移到另一个集合,这样,被转移元素的集合平均值提升最大,且被转移元素集合的平均值提升最小。
代码
public static int f2(int[] arr1,int[] arr2){
double sum1=0;
for (int i = 0; i < arr1.length; i++) {
sum1+=arr1[i];
}
double sum2=0;
for (int i = 0; i < arr2.length; i++) {
sum2+=arr2[i];
}
if(avg(sum1,arr1.length)==avg(sum2,arr2.length)){
return 0;
}
int[] arrMore;
int[] arrLess;
int moreNum;
int lessNum;
double more;
double less;
if(avg(sum1,arr1.length)<avg(sum2,arr2.length)){
arrMore=arr2;
arrLess=arr1;
moreNum=arr2.length;
lessNum=arr1.length;
more=sum2;
less=sum1;
}else {
arrMore=arr1;
arrLess=arr2;
moreNum=arr1.length;
lessNum=arr2.length;
more=sum1;
less=sum2;
}
Arrays.sort(arrMore);
HashSet<Integer> set=new HashSet<>();
for (int i = 0; i < arrLess.length; i++) {
set.add(arrLess[i]);
}
int res=0;
for (int i = 0; i < arrMore.length; i++) {
if(arrMore[i]<avg(more,moreNum)&&arrMore[i]>avg(less,lessNum)&&!set.contains(arrMore[i])){
more-=arrMore[i];
less+=arrMore[i];
moreNum--;
lessNum++;
set.add(arrMore[i]);
res++;
}
}
return res;
}