题目链接:1450. 在既定时间做作业的学生人数 - 力扣(LeetCode)
注:下述题目描述和示例均来自力扣
题目描述
给你两个整数数组 startTime
(开始时间)和 endTime
(结束时间),并指定一个整数 queryTime
作为查询时间。
已知,第 i
名学生在 startTime[i]
时开始写作业并于 endTime[i]
时完成作业。
请返回在查询时间 queryTime
时正在做作业的学生人数。形式上,返回能够使 queryTime
处于区间 [startTime[i], endTime[i]]
(含)的学生人数。
示例
示例一:
示例 1:
输入:startTime = [1,2,3], endTime = [3,2,7], queryTime = 4 输出:1 解释:一共有 3 名学生。 第一名学生在时间 1 开始写作业,并于时间 3 完成作业,在时间 4 没有处于做作业的状态。 第二名学生在时间 2 开始写作业,并于时间 2 完成作业,在时间 4 没有处于做作业的状态。 第三名学生在时间 3 开始写作业,预计于时间 7 完成作业,这是是唯一一名在时间 4 时正在做作业的学生。
示例 2:
输入:startTime = [4], endTime = [4], queryTime = 4 输出:1 解释:在查询时间只有一名学生在做作业。
示例 3:
输入:startTime = [4], endTime = [4], queryTime = 5 输出:0
示例 4:
输入:startTime = [1,1,1,1], endTime = [1,3,2,4], queryTime = 7 输出:0
示例 5:
输入:startTime = [9,8,7,6,5,4,3,2,1], endTime = [10,10,10,10,10,10,10,10,10], queryTime = 5 输出:5
提示:
startTime.length == endTime.length
1 <= startTime.length <= 100
1 <= startTime[i] <= endTime[i] <= 1000
1 <= queryTime <= 1000
解法一:枚举(秒杀)
实现思路是通过遍历startTime和endTime数组,对比每个学生的开始时间和结束时间与查询时间的关系,将满足条件的学生数量加1,并返回最后的结果。具体的实现步骤如下:
- 初始化变量len为startTime数组的长度,表示学生数量。
- 初始化变量index为0,表示当前遍历的学生下标。
- 初始化变量res为0,表示满足条件的学生数量。
- 进入循环,每次循环减少len的值。
- 检查当前学生的开始时间startTime[index]是否小于等于查询时间queryTime,并且结束时间endTime[index]是否大于等于查询时间queryTime。如果满足这两个条件,则将res加1。
- 将index加1,以便遍历下一个学生的开始时间和结束时间。
- 循环结束后,返回res作为结果。
整体思路是通过遍历学生的开始时间和结束时间,检查每个学生是否在查询时间范围内,然后对满足条件的学生数量进行统计。
class Solution {
public int busyStudent(int[] startTime, int[] endTime, int queryTime) {
int len = startTime.length;
int index = 0;
int res = 0;
while(len > 0){
len--;
if(queryTime >= startTime[index] &&
queryTime <= endTime[index]){
res++;
}
index++;
}
return res;
}
}
根据这题的测试数据规模真的是太简单了,暴力都能过
解法二:二分查找
这次的二分纯粹是为了秀肌肉的产物,一点提升没有甚至时间复杂度还增加为了nlogn这你受得鸟吗?
-
排序:
- 使用
Arrays.sort()
对startTime
和endTime
进行排序,以便二分查找能够正常工作。
- 使用
-
upperBound 和 lowerBound 的实现:
upperBound
: 查找第一个大于queryTime
的元素的索引位置,等价于 C++ 中的upper_bound
。lowerBound
: 查找第一个不小于queryTime
的元素的索引位置,等价于 C++ 中的lower_bound
。
-
计算:
lessStart
表示开始时间小于等于queryTime
的学生数量。lessEnd
表示结束时间小于queryTime
的学生数量。- 最后返回
lessStart - lessEnd
作为在queryTime
时正在做作业的学生人数。
class Solution {
public int busyStudent(int[] startTime, int[] endTime, int queryTime) {
// 将startTime和endTime数组排序
Arrays.sort(startTime);
Arrays.sort(endTime);
// 使用二分查找计算小于等于queryTime的startTime数量
int lessStart = upperBound(startTime, queryTime);
// 使用二分查找计算小于queryTime的endTime数量
int lessEnd = lowerBound(endTime, queryTime);
// 返回两者之差
return lessStart - lessEnd;
}
// 实现upper_bound等价的函数
private int upperBound(int[] arr, int target) {
int left = 0, right = arr.length;
while (left < right) {
int mid = left + (right - left) / 2;
if (arr[mid] <= target) {
left = mid + 1;
} else {
right = mid;
}
}
return left;
}
// 实现lower_bound等价的函数
private int lowerBound(int[] arr, int target) {
int left = 0, right = arr.length;
while (left < right) {
int mid = left + (right - left) / 2;
if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid;
}
}
return left;
}
}
果然暴力才是这个世界上最优美的算法 !!
总结
貌似通过二分来解决这个问题,实在是多写太多东西了,不如暴力。