差分数组(TreeMap / Object.create(null) / Array / redblacktree.NewWithIntComparator 红黑树)、顺序遍历、二分查找(upper_bound + bisect_right + sort.Search + sort.SearchInts / lower_bound + bisect_left + sort.Search + sort.SearchInts) 3 种算法,用升序(sort / Arrays.sort / Array.Sort / qsort(int*, int, sizeof(int), cmp) / sort.Ints)技巧,求解《1450. 在既定时间做作业的学生人数》
给你两个整数数组 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
var busyStudent = function(startTime, endTime, queryTime) { // Object 实现
const treeMap = Object.create(null), n = startTime.length
for (let i = 0; i < n; i++) {
const start = startTime[i], end = endTime[i]
treeMap[start] = (treeMap[start] || 0) + 1
treeMap[end + 1] = (treeMap[end + 1] || 0) - 1
}
let r = 0
for (const [time, times] of Object.entries(treeMap)) {
if (queryTime < time) return r
r += times
}
return r
}; var busyStudent = function(startTime, endTime, queryTime) { // Map 实现
const treeMap = new Map, n = startTime.length
for (let i = 0; i < n; i++) {
const start = startTime[i], end = endTime[i]
treeMap.set(start, (treeMap.get(start) || 0) + 1)
treeMap.set(end + 1, (treeMap.get(end + 1) || 0) - 1)
}
let r = 0
for (const [time, times] of Array.from(treeMap.entries()).sort((a, b) => a[0] - b[0])) {
if (time > queryTime) return r
r += times
}
return r
}; var busyStudent = function(startTime, endTime, queryTime) { // Array 实现
const maxEndTime = _.max(endTime), treeMap = new Int16Array(maxEndTime + 2), n = startTime.length
for (let i = 0; i < n; i++) {
const start = startTime[i], end = endTime[i]
treeMap[start]++
treeMap[end + 1]--
}
let r = 0
for (let time = 0; time <= Math.min(maxEndTime + 1, queryTime); time++) {
if (treeMap[time] === 0) continue
r += treeMap[time]
}
return r
}; function busyStudent(startTime: number[], endTime: number[], queryTime: number): number {
const maxEndTime = Math.max.apply(null, endTime), treeMap = new Array(maxEndTime + 2).fill(0)
for (let i = 0; i <= maxEndTime; i++) {
treeMap[startTime[i]]++
treeMap[endTime[i] + 1]--
}
let r = 0
for (let time = 0; time <= Math.min(maxEndTime + 1, queryTime); time++) {
r += treeMap[time]
}
return r
}; class Solution {
function busyStudent($startTime, $endTime, $queryTime) {
$maxEndTime = max($endTime);
$treeMap = array_fill(0, $maxEndTime + 2, 0);
foreach ($startTime as $i => $start) {
$treeMap[$start]++;
$treeMap[$endTime[$i] + 1]--;
}
$r = 0;
for ($time = 0; $time <= min($maxEndTime + 1, $queryTime); $time++) {
$r += $treeMap[$time];
}
return $r;
}
} type TreeMap struct { // redblacktree 实现
*redblacktree.Tree
}
func Constructor() TreeMap {
return TreeMap{redblacktree.NewWithIntComparator()}
}
func (this *TreeMap) Add(key int, value int) {
if v, ok := this.Get(key); ok {
value += v.(int)
}
this.Put(key, value)
}
func busyStudent(startTime []int, endTime []int, queryTime int) int {
treeMap := Constructor()
for i, start := range startTime {
end := endTime[i]
treeMap.Add(start, 1)
treeMap.Add(end + 1, -1)
}
r := 0
for it := treeMap.Iterator(); it.Next(); {
if it.Key().(int) > queryTime {
return r
}
r += it.Value().(int)
}
return r
} func busyStudent(startTime []int, endTime []int, queryTime int) int { // []int 实现
maxEndTime := 0
for _, end := range endTime {
maxEndTime = max(maxEndTime, end)
}
treeMap, r := make([]int, maxEndTime + 2), 0
for i, start := range startTime {
end := endTime[i]
treeMap[start]++
treeMap[end + 1]--
}
for time := 0; time <= min(maxEndTime + 1, queryTime); time++ {
r += treeMap[time]
}
return r
}
func max(a int, b int) int {
if a > b {
return a
}
return b
}
func min(a int, b int) int {
if a < b {
return a
}
return b
} from sortedcontainers import SortedDict # soretedcontainers 实现
class Solution:
def busyStudent(self, startTime: List[int], endTime: List[int], queryTime: int) -> int:
treeMap, r = SortedDict(), 0
for i, start in enumerate(startTime):
treeMap[start] = treeMap.get(start, 0) + 1
treeMap[endTime[i] + 1] = treeMap.get(endTime[i] + 1, 0) - 1
for time, times in treeMap.items():
if time > queryTime: return r
r += times
return r class Solution: # list 实现
def busyStudent(self, startTime: List[int], endTime: List[int], queryTime: int) -> int:
maxEndTime = max(endTime)
treeMap, r = [0] * (maxEndTime + 2), 0
for i, start in enumerate(startTime):
end = endTime[i]
treeMap[start] += 1
treeMap[end + 1] -= 1
for time in range(min(maxEndTime + 2, queryTime + 1)):
r += treeMap[time]
return r class Solution {
public int busyStudent(int[] startTime, int[] endTime, int queryTime) {
TreeMap<Integer, Integer> treeMap = new TreeMap<Integer, Integer>();
int n = startTime.length, r = 0;
for (int i = 0; i < n; i++) {
int start = startTime[i], end = endTime[i];
treeMap.put(start, treeMap.getOrDefault(start, 0) + 1);
treeMap.put(end + 1, treeMap.getOrDefault(end + 1, 0) - 1);
}
for (Map.Entry<Integer, Integer> entry : treeMap.entrySet()) {
int time = entry.getKey(), times = entry.getValue();
if (time > queryTime) return r;
r += times;
}
return r;
}
} public class Solution { // int[] 实现
public int BusyStudent(int[] startTime, int[] endTime, int queryTime) {
int maxEndTime = endTime.Max(), n = startTime.Length, r = 0;
int[] treeMap = new int[maxEndTime + 2];
for (int i = 0; i < n; i++) {
treeMap[startTime[i]]++;
treeMap[endTime[i] + 1]--;
}
for (int time = 0; time <= Math.Min(maxEndTime + 1, queryTime); time++) {
r += treeMap[time];
}
return r;
}
} #define MAX(a, b) a > b ? a : b
#define MIN(a, b) a < b ? a : b
int busyStudent(int* startTime, int startTimeSize, int* endTime, int endTimeSize, int queryTime){ // int* 实现
int maxEndTime = 0;
for (int i = 0; i < endTimeSize; i++) {
maxEndTime = MAX(maxEndTime, endTime[i]);
}
int* treeMap = malloc(sizeof(int) * (maxEndTime + 2));
memset(treeMap, 0, sizeof(int) * (maxEndTime + 2));
for (int i = 0; i < endTimeSize; i++) {
treeMap[startTime[i]]++;
treeMap[endTime[i] + 1]--;
}
int r = 0, minTime = MIN(maxEndTime + 1, queryTime);
for (int time = 0; time <= minTime; time++) {
r += treeMap[time];
}
free(treeMap);
return r;
} class Solution { // vector<int> 实现
public:
int busyStudent(vector<int>& startTime, vector<int>& endTime, int queryTime) {
int maxEndTime = *max_element(endTime.begin(), endTime.end()), r = 0;
vector<int> treeMap(maxEndTime + 2, 0);
for (int i = 0; i < startTime.size(); i++) {
treeMap[startTime[i]]++;
treeMap[endTime[i] + 1]--;
}
for (int time = 0; time <= min(maxEndTime + 1, queryTime); time++) {
r += treeMap[time];
}
return r;
}
}; var busyStudent = function(startTime, endTime, queryTime) {
const n = startTime.length
let r = 0
for (let i = 0; i < n; i++) {
if (startTime[i] <= queryTime && endTime[i] >= queryTime) r++
}
return r
}; function busyStudent(startTime: number[], endTime: number[], queryTime: number): number {
const n = startTime.length
let r = 0
for (let i = 0; i < n; i++) {
if (startTime[i] <= queryTime && endTime[i] >= queryTime) r++
}
return r
}; class Solution {
function busyStudent($startTime, $endTime, $queryTime) {
$r = 0;
foreach ($startTime as $i => $start) {
if ($queryTime >= $start && $queryTime <= $endTime[$i]) $r++;
}
return $r;
}
} func busyStudent(startTime []int, endTime []int, queryTime int) int {
r := 0
for i, start := range startTime {
if queryTime >= start && queryTime <= endTime[i] {
r++
}
}
return r
} class Solution:
def busyStudent(self, startTime: List[int], endTime: List[int], queryTime: int) -> int:
r = 0
for i, start in enumerate(startTime):
if queryTime >= start and queryTime <= endTime[i]: r += 1
return r class Solution {
public int busyStudent(int[] startTime, int[] endTime, int queryTime) {
int n = startTime.length, r = 0;
for (int i = 0; i < n; i++) {
if (queryTime >= startTime[i] && queryTime <= endTime[i]) r++;
}
return r;
}
} public class Solution {
public int BusyStudent(int[] startTime, int[] endTime, int queryTime) {
int n = startTime.Length, r = 0;
for (int i = 0; i < n; i++) {
if (queryTime >= startTime[i] && queryTime <= endTime[i]) r++;
}
return r;
}
} int busyStudent(int* startTime, int startTimeSize, int* endTime, int endTimeSize, int queryTime){
int r = 0;
for (int i = 0; i < startTimeSize; i++) {
if (queryTime >= startTime[i] && queryTime <= endTime[i]) r++;
}
return r;
} class Solution {
public:
int busyStudent(vector<int>& startTime, vector<int>& endTime, int queryTime) {
int r = 0, n = startTime.size();
for (int i = 0; i < n; i++) {
if (queryTime >= startTime[i] && queryTime <= endTime[i]) r++;
}
return r;
}
}; var busyStudent = function(startTime, endTime, queryTime) {
startTime.sort((a, b) => a - b)
endTime.sort((a, b) => a - b)
return upper_bound(startTime, queryTime) - lower_bound(endTime, queryTime)
};
const upper_bound = (nums, num) => {
let l = 0, r = nums.length - 1
while (l <= r) {
const m = l + r >>> 1
if (nums[m] > num) r = m - 1
else l = m + 1
}
return l
}
const lower_bound = (nums, num) => {
let l = 0, r = nums.length - 1
while (l <= r) {
const m = l + r >>> 1
if (nums[m] >= num) r = m - 1
else l = m + 1
}
return l
} function busyStudent(startTime: number[], endTime: number[], queryTime: number): number {
startTime.sort((a, b) => a - b)
endTime.sort((a, b) => a - b)
return upper_bound(startTime, queryTime) - lower_bound(endTime, queryTime)
};
const upper_bound = (nums, num) => {
let l = 0, r = nums.length - 1
while (l <= r) {
const m = l + r >>> 1
if (nums[m] > num) r = m - 1
else l = m + 1
}
return l
}
const lower_bound = (nums, num) => {
let l = 0, r = nums.length - 1
while (l <= r) {
const m = l + r >>> 1
if (nums[m] >= num) r = m - 1
else l = m + 1
}
return l
} class Solution {
function busyStudent($startTime, $endTime, $queryTime) {
sort($startTime, SORT_NUMERIC);
sort($endTime, SORT_NUMERIC);
return $this->upper_bound($startTime, $queryTime) - $this->lower_bound($endTime, $queryTime);
}
function upper_bound($nums, $num) {
$l = 0;
$r = count($nums) - 1;
while ($l <= $r) {
$m = $l + $r >> 1;
if ($nums[$m] > $num) $r = $m - 1;
else $l = $m + 1;
}
return $l;
}
function lower_bound($nums, $num) {
$l = 0;
$r = count($nums) - 1;
while ($l <= $r) {
$m = $l + $r >> 1;
if ($nums[$m] >= $num) $r = $m - 1;
else $l = $m + 1;
}
return $l;
}
} func busyStudent(startTime []int, endTime []int, queryTime int) int {
sort.Ints(startTime)
sort.Ints(endTime)
n := len(startTime)
return sort.Search(n, func(i int) bool {
return startTime[i] > queryTime
}) - sort.Search(n, func(i int) bool {
return endTime[i] >= queryTime
})
} func busyStudent(startTime []int, endTime []int, queryTime int) int {
sort.Ints(startTime)
sort.Ints(endTime)
return sort.SearchInts(startTime, queryTime + 1) - sort.SearchInts(endTime, queryTime)
} class Solution:
def busyStudent(self, startTime: List[int], endTime: List[int], queryTime: int) -> int:
return bisect_right(sorted(startTime), queryTime) - bisect_left(sorted(endTime), queryTime) class Solution {
public int busyStudent(int[] startTime, int[] endTime, int queryTime) {
Arrays.sort(startTime);
Arrays.sort(endTime);
return upper_bound(startTime, queryTime) - lower_bound(endTime, queryTime);
}
public int upper_bound(int[] nums, int num) {
int l = 0, r = nums.length - 1;
while (l <= r) {
int m = l + r >>> 1;
if (nums[m] > num) r = m - 1;
else l = m + 1;
}
return l;
}
public int lower_bound(int[] nums, int num) {
int l = 0, r = nums.length - 1;
while (l <= r) {
int m = l + r >>> 1;
if (nums[m] >= num) r = m - 1;
else l = m + 1;
}
return l;
}
} public class Solution {
public int BusyStudent(int[] startTime, int[] endTime, int queryTime) {
Array.Sort(startTime);
Array.Sort(endTime);
return upper_bound(startTime, queryTime) - lower_bound(endTime, queryTime);
}
public int upper_bound(int[] nums, int num) {
int l = 0, r = nums.Length - 1;
while (l <= r) {
int m = l + r >> 1;
if (nums[m] > num) r = m - 1;
else l = m + 1;
}
return l;
}
public int lower_bound(int[] nums, int num) {
int l = 0, r = nums.Length - 1;
while (l <= r) {
int m = l + r >> 1;
if (nums[m] >= num) r = m - 1;
else l = m + 1;
}
return l;
}
} static inline int cmp(const void *pa, const void *pb) {
return *(int*)pa - *(int*)pb;
}
int upper_bound(int* nums, int* num, int* numsSize) {
int l = 0, r = *numsSize - 1;
while (l <= r) {
int m = l + r >> 1;
if (nums[m] > *num) r = m - 1;
else l = m + 1;
}
return l;
}
int lower_bound(int* nums, int* num, int* numsSize) {
int l = 0, r = *numsSize - 1;
while (l <= r) {
int m = l + r >> 1;
if (nums[m] >= *num) r = m - 1;
else l = m + 1;
}
return l;
}
int busyStudent(int* startTime, int startTimeSize, int* endTime, int endTimeSize, int queryTime){
qsort(startTime, startTimeSize, sizeof(int), cmp);
qsort(endTime, endTimeSize, sizeof(int), cmp);
return upper_bound(startTime, &queryTime, &startTimeSize) - lower_bound(endTime, &queryTime, &endTimeSize);
} class Solution {
public:
int busyStudent(vector<int>& startTime, vector<int>& endTime, int queryTime) {
sort(startTime.begin(), startTime.end());
sort(endTime.begin(), endTime.end());
return upper_bound(startTime.begin(), startTime.end(), queryTime) - startTime.begin() - (lower_bound(endTime.begin(), endTime.end(), queryTime) - endTime.begin());
}
};