【每日一题】LeetCode.2860让所有学生保持开心的分组方法数(枚举、数组、排序)
题目描述
给定一个整数数组 nums
,表示班级中学生的总数,班主任希望在让所有学生保持开心的情况下选出一组学生。如果满足以下两个条件之一,则认为第 i
位学生将会保持开心:
- 这位学生被选中,并且被选中的学生人数严格大于
nums[i]
。 - 这位学生没有被选中,并且被选中的学生人数严格小于
nums[i]
。
返回能够满足让所有学生保持开心的分组方法的数目。
思路分析
这个问题可以通过排序和枚举的方法来解决。首先,我们需要对数组 nums
进行排序,这样我们可以更方便地找到满足条件的学生分组。
- 排序:将数组
nums
从小到大排序。 - 枚举:枚举所有可能的选中学生人数
k
,从 0 到n
(n
是班级中学生的总数)。 - 检查条件:对于每个
k
,我们需要检查是否所有学生都满足开心条件:- 所有满足
nums[i] < k
的学生应被选中。 - 所有满足
nums[i] > k
的学生不应被选中。 - 不能存在
nums[i] == k
的学生。
- 所有满足
- 边界处理:在枚举过程中,需要特别注意边界情况,即
k = 0
和k = n
的情况。 - 计数:如果某个
k
值满足所有条件,则增加可行方案的计数。
输入示例
示例 1:
输入:nums = [1,1]
输出:2
解释:
有两种可行的方法:
班主任没有选中学生。
班主任选中所有学生形成一组。
如果班主任仅选中一个学生来完成分组,那么两个学生都无法保持开心。因此,仅存在两种可行的方法。
示例 2:
输入:nums = [6,0,3,3,6,7,2,7]
输出:3
解释:
存在三种可行的方法:
班主任选中下标为 1 的学生形成一组。
班主任选中下标为 1、2、3、6 的学生形成一组。
班主任选中所有学生形成一组。
代码实现
import java.util.Collections;
import java.util.List;
class Solution {
public int countWays(List<Integer> nums) {
int n = nums.size();
// 初始化结果计数器
int res = 0;
// 对数组进行排序
Collections.sort(nums);
// 枚举所有可能的选中学生人数 k
for (int k = 0; k <= n; k++) {
// 初始化两个标志变量,分别表示选中和未选中的学生是否满足条件
boolean selected = true;
boolean notSelected = true;
// 检查选中的学生是否满足条件
for (int i = 0; i < k; i++) {
if (nums.get(i) >= k) {
selected = false;
break;
}
}
// 检查未选中的学生是否满足条件
for (int i = k; i < n; i++) {
if (nums.get(i) <= k) {
notSelected = false;
break;
}
}
// 如果当前 k 值满足所有条件,则增加结果计数
if (selected && notSelected) {
res++;
}
}
return res;
}
}