759. Employee Free Time

sweep-line - use priorityQeueu

T: O(nlogn)

S: O(n)

/*
// Definition for an Interval.
class Interval {
    public int start;
    public int end;

    public Interval() {}

    public Interval(int _start, int _end) {
        start = _start;
        end = _end;
    }
};
*/

class Solution {
    private static final int START = 1;
    private static final int END = -1;
    
    class TimeInfo {
        int value;
        int type;
        TimeInfo(int value, int type) {
            this.value = value;
            this.type = type;
        }
    }
    public List<Interval> employeeFreeTime(List<List<Interval>> schedule) {
        Queue<TimeInfo> pq = new PriorityQueue<>((a, b) -> {
            return a.value == b.value ? a.type - b.type : a.value - b.value;
        });
        for (List<Interval> list : schedule) {
            for (Interval in : list) {
                pq.offer(new TimeInfo(in.start, START)); // start time
                pq.offer(new TimeInfo(in.end, END)); // end time
            }
        }
        
        List<Interval> res = new ArrayList<>();
        int count = 0;
        while (pq.size() > 1) { // need at least 2 data in pq, then we can do the operation
            TimeInfo left = pq.poll();
            TimeInfo right = pq.peek();
            count += left.type;
            // there is a test case [91,94], [94,99] => [94,94], this test can't allow, so check this
            if (left.type == END && right.type == START && count == 0 && left.value != right.value) {
                res.add(new Interval(left.value, right.value));
            }
        }
        return res;
    }
}


/*
[[[1,2],[5,6]],[[1,3]],[[4,10]]]

count = s(1) + e(-1)...

   left right. => if left == e && right == s && count == 0
      |-|
1 1 2 3 4 5 6 10
s s e e s s e  s 
1 2 1 0 1 2 1  2      count  
*/

sweep-line - use treemap

https://leetcode.com/problems/employee-free-time/discuss/175081/Sweep-line-Java-with-Explanations

/*
// Definition for an Interval.
class Interval {
    public int start;
    public int end;

    public Interval() {}

    public Interval(int _start, int _end) {
        start = _start;
        end = _end;
    }
};
*/

class Solution {
    private static final int START = 1;
    private static final int END = -1;
    
    public List<Interval> employeeFreeTime(List<List<Interval>> schedule) {
        TreeMap<Integer, Integer> map = new TreeMap<>();
        
        for (List<Interval> list : schedule) {
            for (Interval in : list) {
                // because use treeMap, so the key will overlap, the START, END should accumulate
                map.put(in.start, map.getOrDefault(in.start, 0) + START); // start time
                map.put(in.end, map.getOrDefault(in.end, 0) + END); // end time
            }
        }
        
        List<Interval> res = new ArrayList<>();
        int count = 0;
        int startFreeTime = -1; // -1 means don't have startFreeTime now
        
        for (int key : map.keySet()) { // need at least 2 data in pq, then we can do the operation
            count += map.get(key);
            if (count == 0 && startFreeTime == -1) { // count == 0, means free time start
                startFreeTime = key;
            // have startFreeTime in pre loop, means we can record endFreeTime now
            } else if (startFreeTime != -1) {
                res.add(new Interval(startFreeTime, key));
                startFreeTime = -1;
            }
        }
        return res;
    }
}


/*
[[[1,2],[5,6]],[[1,3]],[[4,10]]]

count = s(1) + e(-1)...

   if count == 0, save startFreeTime, in next loop, we'll get endFreeTime
  startFreeTime     
      |-|
1 1 2 3 4 5 6 10
s s e e s s e  s 
1 2 1 0 1 2 1  2      count  
*/

Last updated