Give two users' ordered online time series, and each section records the user's login time point x
and offline time point y
. Find out the time periods when both users are online at the same time, and output in ascending order.you need return a list of intervals.
Example
Example 1:
Input: seqA = [(1,2),(5,100)], seqB = [(1,6)]
Output: [(1,2),(5,6)]
Explanation: In these two time periods (1,2), (5,6), both users are online at the same time.
Example 2:
Input: seqA = [(1,2),(10,15)], seqB = [(3,5),(7,9)]
Output: []
Explanation: There is no time period, both users are online at the same time.
Notice
- We guarantee that the length of online time series meet
1 <= len <= 1e6
. - For a user's online time series, any two of its sections do not intersect.
思路1:扫描线算法,把起点和终点分别记录为1,0,(上线和下线),然后按照time sort一下
count == 2 则开始记录start,count从2下降,则记录end;注意下降的时候,一定要从count == 2的时候开始记录;否则1 -> 0也会记录进去;Time: (n+m) * log(n+m);
/**
* Definition of Interval:
* public classs Interval {
* int start, end;
* Interval(int start, int end) {
* this.start = start;
* this.end = end;
* }
* }
*/
public class Solution {
/**
* @param seqA: the list of intervals
* @param seqB: the list of intervals
* @return: the time periods
*/
private class Node {
public int time;
public int flag;
public Node(int time, int flag) {
this.time = time;
this.flag = flag;
}
}
public List<Interval> timeIntersection(List<Interval> seqA, List<Interval> seqB) {
List<Node> list = new ArrayList<>();
List<Interval> result = new ArrayList<>();
for(Interval interA: seqA) {
list.add(new Node(interA.start, 1));
list.add(new Node(interA.end, -1));
}
for(Interval interB: seqB) {
list.add(new Node(interB.start, 1));
list.add(new Node(interB.end, -1));
}
Collections.sort(list, (a, b) -> (a.time != b.time
? a.time - b.time
: a.flag - b.flag));
int count = 0;
int start = -1; int end = -1;
for(Node node: list) {
if(node.flag == 1) {
count++;
if(count == 2) {
start = node.time;
}
}
if(node.flag == -1) {
if(count == 2) {
end = node.time;
result.add(new Interval(start, end));
start = -1;
end = -1;
}
count--;
}
}
return result;
}
}
思路2:因为A和B都是sorted,那么跟merge array一样,可以用打擂台的方式,每次踢走一个。
如果Max(startA, startB) < Min(endA, endB)则加入相交的interval
看A, B end 谁大,谁留下,另外一个踢走;O(N+M)
/**
* Definition of Interval:
* public classs Interval {
* int start, end;
* Interval(int start, int end) {
* this.start = start;
* this.end = end;
* }
* }
*/
public class Solution {
/**
* @param seqA: the list of intervals
* @param seqB: the list of intervals
* @return: the time periods
*/
public List<Interval> timeIntersection(List<Interval> seqA, List<Interval> seqB) {
List<Interval> list = new ArrayList<Interval>();
if(seqA == null || seqA.size() == 0 || seqB == null || seqB.size() == 0) return list;
int a = 0; int b = 0;
while(a < seqA.size() && b < seqB.size()){
int start = Math.max(seqA.get(a).start, seqB.get(b).start);
int end = Math.min(seqA.get(a).end, seqB.get(b).end);
if(start < end) {
list.add(new Interval(start, end));
}
if(seqA.get(a).end < seqB.get(b).end){
a++;
} else {
b++;
}
}
return list;
}
}