思路:区域覆盖问题。一个自然的想法是将每个员工的工作时间段看做一个木棒,每个木棒的长度就是这个时间段的时长。然后按照木棒的起始位置升序排列,接着由低位置向高位置一个木棒一个木棒的看过去。如果当前木棒的末节点的位置>下一个木棒的头节点位置,那么这两个节点就是一个free time的开头和结尾;如果当前木棒的末节点位置<=下一个木棒的头节点位置,那么更新当前木棒的末节点位置为max(当前木棒的末节点位置,下一个木棒的头节点位置)。
1 /** 2 * Definition for an interval. 3 * public class Interval { 4 * int start; 5 * int end; 6 * Interval() { start = 0; end = 0; } 7 * Interval(int s, int e) { start = s; end = e; } 8 * } 9 */ 10 class Solution { 11 public List<Interval> employeeFreeTime(List<List<Interval>> schedule) { 12 List<Interval> res = new ArrayList<>(); 13 PriorityQueue<Interval> pq = new PriorityQueue<>((a,b)->a.start - b.start);//按照第一个元素升序排列 14 schedule.forEach(e->pq.addAll(e));//lamdba表达式,将schedule的每个元素的每个子元素加入pq中 15 Interval before = pq.poll(); 16 while(!pq.isEmpty()) { 17 if(before.end < pq.peek().start) { 18 res.add(new Interval(before.end, pq.peek().start)); 19 before = pq.poll(); 20 }else{ 21 before = before.end < pq.peek().end ? pq.peek() : before;//这里不能写成before = before.end < pq.peek().end ? pq.poll() : before;会Time Limit Exceeded 22 pq.poll(); 23 } 24 } 25 return res; 26 } 27 }