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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package airbnb;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;


/**
* 每个subarray都已经sort好
举例:
[
  [[1, 3], [6, 7]],
  [[2, 4]],
  [[2, 3], [9, 12]].
]
返回
[[4, 6], [7, 9]]
N个员工,每个员工有若干个interval表示在这段时间是忙碌的。求所有员工都不忙的intervals
解法:这题最简单的方法就是把所有区间都拆成两个点,然后排序,然后扫描,每次碰到一个点如果
是左端点就把busy_employees加1,否则减1,等到每次busy_employees为0时就是一个新的区间。
这样复杂度O(MlogM),M是总共区间数。但是我当时也不知道是脑抽了还是脑子太好用了,弄了个堆的,
堆里N个元素,存每个员工的下一个端点,如果堆顶是某个员工的左端点就busy_employees加1,否则减1。
这样好处是时间复杂度低了一点点,坏处是给面试官讲了半天而且代码不是太好写……不建议这么做.
* @author yihuifu
*
*/

public class MeetingIntervals {

public static void main(String[] args) {
MeetingIntervals meetingIntervals = new MeetingIntervals();
List<List<Interval>> intervals = new LinkedList<>();
for (int i = 0; i < 3; i++) {
intervals.add(new LinkedList<>());
switch (i) {
case 0:
intervals.get(i).add(meetingIntervals.new Interval(1,3));
intervals.get(i).add(meetingIntervals.new Interval(6,7));
break;
case 1:
intervals.get(i).add(meetingIntervals.new Interval(2,8));
break;
case 2:
intervals.get(i).add(meetingIntervals.new Interval(2,3));
intervals.get(i).add(meetingIntervals.new Interval(9,12));
break;
}
}
List<Interval> freeIntervals = meetingIntervals.findFreeIntervals(intervals);
for (Interval interval : freeIntervals) {
System.out.println(interval.toString());
}
}

public List<Interval> findFreeIntervals(List<List<Interval>> intervals) {
List<Interval> result = new LinkedList<>();
if (intervals == null || intervals.size() == 0) {
return result;
}
LinkedList<Interval> all = new LinkedList<>();
for (int i = 0; i < intervals.size(); i++) {
for (int j = 0; j < intervals.get(i).size(); j++) {
all.add(intervals.get(i).get(j));
}
}
Collections.sort(all, (a,b) -> (a.startTime - b.startTime));
PriorityQueue<Interval> pq = new PriorityQueue<>((a,b) -> a.endTime - b.endTime);
pq.offer(all.get(0));
for (int i = 1; i < all.size(); i++) {
Interval prev = pq.poll();
Interval cur = all.get(i);
if (cur.startTime <= prev.endTime) {
prev.endTime = Math.max(prev.endTime, cur.endTime);
} else {
pq.offer(cur);
}
pq.offer(prev);
}
Interval prev = pq.poll();
while (!pq.isEmpty()) {
Interval cur = pq.poll();
result.add(new Interval(prev.endTime, cur.startTime));
prev = cur;
}
return result;
}

public class Interval {
int startTime;
int endTime;

public Interval(int start, int end) {
startTime = start;
endTime = end;
}

@Override
public String toString() {
return "" + startTime + " " + endTime;
}
}

}