问题描述
公司正在进行优秀项目组评比的初选工作,参赛者有小C、小U、小R、小S、小M和小F的项目组。评委会已经根据他们提交的材料完成了打分,各个项目组的得分分别是。评委们希望设定一个初选晋级的分数线,让所有得分大于的项目组晋级,其他的项目组将被淘汰。此外,评委们希望晋级的项目组数量和淘汰的项目组数量都在区间之间。 显然,这个分数线可能不存在,也可能存在多个满足条件的分数线。如果不存在满足条件的,则输出;如果存在多个满足条件的分数线,则输出满足条件的最小分数线。
为了实现这个功能,我们需要根据题目的要求,选择一个合适的分数线 x,使得晋级的项目组数量和淘汰的项目组数量都在区间 [m, n] 之间。
解题思路:
-
输入说明:
m和n是晋级项目组数量的下限和上限。a是一个数组,表示各个项目组的得分。
-
要求:
- 设定一个分数线
x,使得所有得分大于x的项目组晋级,其余的项目组淘汰。 - 晋级的项目组数量应在
[m, n]范围内。 - 如果满足条件的分数线存在多个,则选择最小的分数线。
- 如果不存在满足条件的分数线,则返回
-1。
- 设定一个分数线
解决步骤:
-
排序得分数组:
- 将得分数组
a排序,便于后续处理。
- 将得分数组
-
遍历可能的分数线:
- 分数线
x可以是得分数组中每个项目组的得分值。假设我们选择一个分数线x,则所有得分大于x的项目组将晋级,剩下的项目组将被淘汰。
- 分数线
-
计算晋级和淘汰人数:
- 对于每个分数线,计算有多少项目组的得分大于该分数线,即晋级的项目组数量。
- 计算淘汰的项目组数量,即总人数减去晋级人数。
- 如果晋级人数和淘汰人数都在
[m, n]范围内,则该分数线是有效的。
-
选择最小分数线:
- 选择最小的符合条件的分数线
x。
- 选择最小的符合条件的分数线
-
返回结果:
- 如果找到了符合条件的分数线,返回该分数线。
- 如果找不到符合条件的分数线,返回
-1。
代码实现:
import java.util.Arrays;
public class Main {
public static int solution(int m, int n, int[] a) {
// 对得分数组进行排序
Arrays.sort(a);
int len = a.length;
// 遍历可能的分数线,检查每个可能的分数线 x
for (int i = 0; i < len - 1; i++) {
// 选择分数线 x 为 a[i]
int x = a[i];
// 计算晋级人数,即得分大于 x 的人数
int passedCount = len - 1 - i; // 所有得分大于 a[i] 的项目组数
int eliminatedCount = i + 1; // 所有得分小于等于 a[i] 的项目组数
// 检查晋级人数和淘汰人数是否在 [m, n] 范围内
if (passedCount >= m && passedCount <= n && eliminatedCount >= m && eliminatedCount <= n) {
return x;
}
}
// 如果没有符合条件的分数线
return -1;
}
public static void main(String[] args) {
System.out.println(solution(2, 3, new int[]{1, 2, 3, 5, 6, 4}) == 3);
System.out.println(solution(1, 2, new int[]{7, 8, 9, 3, 5}) == -1);
System.out.println(solution(1, 4, new int[]{7, 8, 9, 3, 5}) == 3);
}
}
解释:
-
排序:
- 我们对得分数组
a进行排序,确保我们可以通过遍历数组来选择每个可能的分数线。
- 我们对得分数组
-
分数线选择:
- 对于每个得分
a[i],我们将其作为分数线x。 passedCount是得分大于x的项目组数量,可以通过计算len - 1 - i来得到(i是x的索引,len是数组长度)。eliminatedCount是得分小于等于x的项目组数量,是i + 1。
- 对于每个得分
-
判断是否满足条件:
- 如果晋级和淘汰的项目组数量都在
[m, n]范围内,则该分数线有效,返回当前分数线x。
- 如果晋级和淘汰的项目组数量都在
-
返回
-1:- 如果遍历所有可能的分数线都没有找到满足条件的,返回
-1。
- 如果遍历所有可能的分数线都没有找到满足条件的,返回
复杂度分析:
- 时间复杂度:排序需要
O(k log k)时间,其中k是数组的长度。遍历数组的时间是O(k),因此总时间复杂度为O(k log k)。 - 空间复杂度:排序操作使用了
O(k)的额外空间。
总结
本题核心算法比较简单,只需要通过对得分进行排序并逐一验证每个可能的分数线,我们能够找到满足条件的最小分数线。如果没有满足条件的分数线,则返回 -1。