leetcode 1450. 在既定时间做作业的学生人数 1094. 拼车
法一:差分数组
class Solution {
public:
int busyStudent(vector<int>& startTime, vector<int>& endTime, int queryTime) {
int nums[1001] = {0};int size = startTime.size();
for(int i = 0;i < size;i++){
nums[startTime[i]]++;
if(endTime[i] < 1000) nums[endTime[i]+1]--;
}
for(int i = 1;i <= queryTime;i++) nums[i] += nums[i-1];
return nums[queryTime];
}
};
法二:枚举
class Solution {
public:
int busyStudent(vector<int>& startTime, vector<int>& endTime, int queryTime) {
int size = startTime.size();
int res = 0;
for (int i = 0; i < size; i++) {
if (startTime[i] <= queryTime && endTime[i] >= queryTime) {
res++;
}
}
return res;
}
};
法三:二分查找(调用stl)
每个学生一定满足:startTime [i] ≤ endTime[i]
如果某个学生在queryTime时刻正在赶作业,那么就一定有 startTime [i] <= queryTime <= endTime [i]
设起始时间小于等于 queryTime 的学生集合为 lessStart,设结束时间小于 queryTime 的学生集合为 lessEnd,则根据上述推理可以知道 lessEnd ∈ lessStart,我们从 lessStart 去除 lessEnd 的子集部分即为符合条件的学生集合。因此我们通过二分查找 找到 始时间 小于等于 queryTime 的学生人数,然后减去结束时间小于 queryTime 的学生人数,最终结果即为符合条件要求。
lower_bound( )和upper_bound( )都是利用二分查找的方法在一个排好序的数组中进行查找的。
在从小到大的排序数组中,lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址(iter),不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址(iter),不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
class Solution {
public:
int busyStudent(vector<int>& startTime, vector<int>& endTime, int queryTime) {
sort(startTime.begin(), startTime.end());
sort(endTime.begin(), endTime.end());
int lessStart = upper_bound(startTime.begin(), startTime.end(), queryTime) - startTime.begin();
int lessEnd = lower_bound(endTime.begin(), endTime.end(), queryTime) - endTime.begin();
return lessStart - lessEnd;
}
};
class Solution {
public:
bool carPooling(vector<vector<int>>& trips, int capacity) {
int max = -1;
for(const auto & trip : trips){
if(trip[2] > max) max = trip[2];
}
int nums[max+1];for(int i = 0;i < max+1;i++) nums[i] = 0;
for(const auto & trip : trips){
if(trip[0] > capacity) return false;
nums[trip[1]] += trip[0];
if(trip[2] <= max){
nums[trip[2]] -= trip[0];//这道题left和right仅表示端点,关键是不同的left和right所表示的段的状态
}
}
for(int i = 1;i < max+1;i++){
nums[i] += nums[i-1];
if(nums[i] > capacity) return false;
}
return true;
}
};