题意整理
- 给定长度为n的数组,将数字大的分配给数字小的,使得尽可能多的数不小于给定数字x。
- 求最多有多少个数不小于x。
方法一(排序+模拟)
1.解题思路
- 首先初始化结果变量和分配之后多余的数。
- 将给定数组排序,逆序遍历,保证每次访问的都是当前最大的,如果大于等于x,说明能分配,则计数加一,并加上对应剩余数。如果小于x,但是剩余数加上当前数字大于等于x,还是能分配,计数加一,减去对应剩余数;否则不能分配,直接终止循环。
动图展示:
2.代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 最多有多少数字不小于x
* @param n int整型
* @param x int整型
* @param a int整型一维数组
* @return int整型
*/
public int arrange (int n, int x, int[] a) {
//初始化结果变量和剩余分配数
int res=0;
int remain=0;
//排序
Arrays.sort(a);
for(int i=n-1;i>=0;i--){
//如果当前数大于x,一定可分配,res加一,同时计算剩余可分的
if(a[i]>=x){
remain+=a[i]-x;
res++;
}
else{
//如果当前数小于x,但是加上剩余数后,大于等于x,则还是可分配
if(remain>=x-a[i]){
remain-=x-a[i];
res++;
}
//否则,不能再分配
else{
break;
}
}
}
return res;
}
} 3.复杂度分析
- 时间复杂度:排序的时间复杂度为
,循环是线性的,复杂度为
,所以时间复杂度为
。
- 空间复杂度:需要额外常数级别的空间,所以空间复杂度为
。
方法二(排序+按平均数试探)
1.解题思路
- 首先初始化结果变量和累加和。
- 将给定数组排序,逆序遍历,统计当前访问到的所有数的累加和,计算出平均数,如果大于等于x,说明可分配,计数加一;否则,终止循环。
2.代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 最多有多少数字不小于x
* @param n int整型
* @param x int整型
* @param a int整型一维数组
* @return int整型
*/
public int arrange (int n, int x, int[] a) {
//初始化结果变量和累加和
long res=0;
long sum=0;
//排序
Arrays.sort(a);
//逆序遍历
for(int i=n-1;i>=0;i--){
//统计累加和
sum+=a[i];
//当前平局数
long avg=sum/(n-i);
//如果大于等于x,说明可分配
if(avg>=x){
res++;
}
//否则终止循环
else{
break;
}
}
return (int)res;
}
} 3.复杂度分析
- 时间复杂度:排序的时间复杂度为
,循环是线性的,复杂度为
,所以时间复杂度为
。
- 空间复杂度:需要额外常数级别的空间,所以空间复杂度为
。

京公网安备 11010502036488号