题目地址:
https://www.lintcode.com/problem/process-sequence/description
给定一系列进程运行的时间的开始和结束点,题目保证时长大于 0 0 0,给定一系列询问,问某个时间点有多少进程在跑。如果一个进程在那个时间点开始,则计入;如果是结束,则不计入。
思路是扫描线。先将进程的所有开始结束点和询问的时间点都做成一个pair,然后按时间排序。如果时间相同,则开始点排在最前,结束点次之,询问时间再次之(注意,这样的顺序是必要的。因为开始的进程是计入的,所以要排在最前面,而结束的进程是不计入的,排在次之,这样再扫描到query的时候,计算出的在跑的进程数是正确的)。接着对pair进行遍历,一边遍历一边算当前有多少个进程在跑。代码如下:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Solution {
class Pair {
int time, flag;
public Pair(int time, int flag) {
this.time = time;
this.flag = flag;
}
}
/**
* @param logs: Sequence of processes
* @param queries: Sequence of queries
* @return: Return the number of processes
*/
public List<Integer> numberOfProcesses(List<Interval> logs, List<Integer> queries) {
// Write your code here
List<Integer> res = new ArrayList<>();
List<Pair> list = new ArrayList<>();
// 将所有时间点连同它的含义做成一个pair加入list
for (Interval log : logs) {
list.add(new Pair(log.start, 0));
list.add(new Pair(log.end, 1));
}
for (int query : queries) {
list.add(new Pair(query, 2));
}
list.sort((p1, p2) -> {
if (p1.time != p2.time) {
return Integer.compare(p1.time, p2.time);
}
return Integer.compare(p1.flag, p2.flag);
});
int count = 0;
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
Pair cur = list.get(i);
if (cur.flag == 0) {
count++;
} else if (cur.flag == 1) {
count--;
}
if (cur.flag == 2) {
map.put(cur.time, count);
}
}
for (int query : queries) {
res.add(map.get(query));
}
return res;
}
}
class Interval {
int start, end;
public Interval(int start, int end) {
this.start = start;
this.end = end;
}
}
时间复杂度 O ( ( n + m ) log ( n + m ) ) O((n+m)\log (n+m)) O((n+m)log(n+m)),空间 O ( n + m ) O(n+m) O(n+m), n n n是log的数量, m m m是询问的数量。