携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第21天,点击查看活动详情
每日刷题 2022.08.19
- leetcode原题链接:leetcode.cn/problems/nu…
- 难度:简单
- 方法: 差分
题目
- 给你两个整数数组 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,数组中的每一个startTime和endTime都是一个学生做作业的时间区间。根据提供的queryTime,需要找到这个时间点在做作业的人数。 - 查看数据范围不是很大,可以直接暴力模拟,对于每一个区间查询,是否包含
queryTime,即startTime[i] <= queryTime && queryTime >= endTime[i]的,将符合要求的区间统计下来即可。
差分
- 新学习的算法,差分和前缀和比较类似,但是和前缀和是相反的操作。
- 差分的适用场景:区间修改、单点查询。常规的板子题可以根据差分的特性去判断是否可以使用,但是也会存在一些题目需要转化后才能使用差分的。
- 举例: 数组
[1,2,5,8],其差分数组是:[1,1,3,3],差分数组的第i个数即为原数组的第i-1个元素和第i个元素的差值,也就是说我们对差分数组求前缀和即可得到原数组.
AC代码
/**
* @param {number[]} startTime
* @param {number[]} endTime
* @param {number} queryTime
* @return {number}
*/
var busyStudent = function(startTime, endTime, queryTime) {
// 区间修改,单点查询
// 区间为什么修改呢?因为不同的区间的人数就不同
let q = queryTime, ans = new Array(q).fill(0), s = startTime, e = endTime, n = s.length;
for(let i = 0; i < n; i++) {
let pre = s[i] - 1, next = e[i] - 1;
ans[pre]++;
if((next + 1) < q) ans[next + 1]--;
}
// console.log(ans)
for(let i = 1; i < q; i++) {
ans[i] = ans[i] + ans[i - 1];
}
// return ans;
return ans[q - 1];
};