【注意】最后更新于 May 18, 2020,文中内容可能已过时,请谨慎使用。
一、题目信息
今天来做450这个题目把,主要考察的利用空间换时间,查询从o(n),优化到o(1)
-
如果能用方法1实现,说明能把时间抽象成一个点.而不是一个间距。我刚开始就疑惑为啥root房间问题直接给出开始时间和结束时间,而是给出2个vector,多此一举。
目的告诉你查询 queryTime也是一个时间点。我纠结在一天24小时,一小时 60分钟,有一分钟 60秒,毫秒,无穷无尽呀!
startTime[i] <= endTime[i] <= 1000
-
如果能用方法2实现,说明理解了多个非线性点在空间上分布,就是离线的,推荐一本书 «离散数学及其应用»。
做什么事情都讲究概率的。例如身高服从正态分布(泊松分布),财富分配二八定律(幂律分布),扯远了。
提示 queryTime <= 1000,空间也是有限的。
- 链接:1450. 在既定时间做作业的学生人数
- 来源:Interview Question
- 难度:Easy
二、题目描述
算法是问题求解过程的一种描述,看看这个题目是怎么描述的吧。
1
2
3
4
5
6
|
提示
startTime.length == endTime.length
1 <= startTime.length <= 100
1 <= startTime[i] <= endTime[i] <= 1000
1 <= queryTime <= 1000
|
三、算法描述
能说出基本思想即可,实在不行动手画个流程图把。
- For multiple queries:

四、参考代码
放轻松,虽然是c++实现,我们一贯宗旨是拒绝奇技淫巧,不懂代码一看就明白
c++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
class Solution {
public:
/***
1 解题思路1:
正确理解题意,查询[startTime[i], endTime[i]]内 包含queryTime有多个区间。
我上来被题目描述看这么多字,然后放弃了。
2.算法描述:
一次性那遍历,判断queryTime >= startTime[i] && queryTime <= endTime[i]个数。
3.复杂度:时间 O(N),空间O(1)
***/
int busyStudent(vector<int>& startTime, vector<int>& endTime, int queryTime) {
int length=startTime.size(); //题目给出条件 startTime.length == endTime.length
int res =0;//时间 抽象成一个整数 例如时间戳, 查询时间也是时间戳。不考虑时间段问题。
//queryTime 处于区间 [startTime[i], endTime[i]](含)的学生人数。
for(int i=0;i<length;i++)
{
if (queryTime >= startTime[i] && queryTime <= endTime[i])
{
res++;
}
}
return res;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
class Solution
{
public:
/***
1 解题思路2:
因为查询时间点,是有限的,开始时间和结束时间也是有点的 不超过1000个
直接计算[0-1001]个点直接 全部同时学习的学生。
For multiple queries:
We can calculate the overlapping intervals at any time by maintaining an array that contains the intervals of all the students.
Doing this requires O(maxm_element + numberOfStudents) time.
2.算法描述:
1. 用开始时间,作为数组下标,遍历开始时间数组。count[start] += 1;
2. 用结束时间,作为数组下标,遍历结束时间数组。 count[end + 1] -= 1;
3. 累加:count[i] += count[i - 1];
3.复杂度:时间 O(N),空间O(N)
int busyStudent(vector<int> &startTime, vector<int> &endTime, int queryTime)
{
//作为一个服务,这里假如每次查询 startTime,endTime固定不变,变化的queryTime.
// 如果每次startTime,endTime都是变化的,这个算法浪费空间了.
vector<int> count(1002, 0); //key 时间点,value 10002是防止end+1越界,[0--1001]
for (auto start : startTime)
{
count[start] += 1;
}
for (auto end : endTime)
{
count[end + 1] -= 1;
}
//[1,100],[2,100],[3,100],[4,100] 在4点,100点同时多少个学生在学习,答案就是4.在101点呢,都结束了。
for (int i = 1; i < 1002; i++)
{
count[i] += count[i - 1];
}
return count[queryTime];
}
};
|
go
1
2
3
4
5
6
7
8
9
10
11
12
13
|
func busyStudent(startTime []int, endTime []int, queryTime int) int {
length:=len(startTime)
res:=0
for i:=0;i<length;i++{
if queryTime>=startTime[i] && queryTime <=endTime[i] {
res++
}
}
return res;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
class Solution {
public:
int busyStudent(vector<int>& startTime, vector<int>& endTime, int queryTime) {
//作为一个服务,这里假如每次查询 startTime,endTime固定不变,变化的queryTime.
// 如果每次startTime,endTime都是变化的,这个算法浪费空间了.
vector<int>count(1002,0);//key 时间点,value 10002是防止end+1越界,[0--1001]
for(auto start:startTime)
{
count[start]+=1;
}
for(auto end:endTime)
{
count[end+1]-=1;
}
//[1,100],[2,100],[3,100],[4,100] 在4点,100点同时多少个学生在学习,答案就是4.在101点呢,都结束了。
for(int i=1;i<1002;i++)
{
count[i]+=count[i-1];
}
return count[queryTime];
}
};
|
五、举一反三
别人最佳答案并不重要,关键是自己理解。
1897-meeting-room-ii
1
2
3
4
5
6
|
输入: intervals = [(0,30),(5,10),(15,20)]
输出: 2
解释:
需要两个会议室
会议室1:(0,30)
会议室2:(5,10),(15,20)
|