Intervals
Employee Free Time
DESCRIPTION (inspired by Leetcode.com)
Write a function to find the common free time for all employees from a list called schedule. Each employee's schedule is represented by a list of non-overlapping intervals sorted by start times. The function should return a list of finite, non-zero length intervals where all employees are free, also sorted in order.
Input:
schedule = [[[2,4],[7,10]],[[1,5]],[[6,9]]]
Output:
[(5,6)]
Explanation: The three employees collectively have only one common free time interval, which is from 5 to 6.
public class Solution {
public int[][] employeeFreeTime(int[][][] schedule) {
// Your code goes here
}
}Run your code to see results here
Have suggestions or found something wrong?
Explanation
This problems builds upon the concept of merging intervals. We can solve this problem by first merging all the employee meeting intervals into a single list. The free times are then the gaps between those merged intervals.
Important Note on Boundaries: In this problem, we only consider the gaps between busy intervals as free time. We do not consider:
- Time before the earliest busy interval (e.g., if the first meeting starts at 9:00 AM, we don't count 8:00-9:00 AM as "free time")
- Time after the latest busy interval (e.g., if the last meeting ends at 5:00 PM, we don't count 5:00-6:00 PM as "free time")
This is because the problem asks for common free time when all employees are available, and we're only given their scheduled busy intervals within a certain working timeframe.
Phase 1
We first want to flatten the list of intervals into a single list, and then sorting them by their start time to make the merge process easier.
public int[][] employeeFreeTime(int[][][] schedule) {List<int[]> flattened = new ArrayList<>();for (int[][] employee : schedule) {for (int[] interval : employee) {flattened.add(interval);}}Collections.sort(flattened, (a, b) -> a[0] - b[0]);List<int[]> merged = new ArrayList<>();for (int[] interval : flattened) {if (merged.isEmpty() || merged.get(merged.size() - 1)[1] < interval[0]) {merged.add(new int[]{interval[0], interval[1]});} else {merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], interval[1]);}}List<int[]> free_times = new ArrayList<>();for (int i = 1; i < merged.size(); i++) {int start = merged.get(i - 1)[1];int end = merged.get(i)[0];if (start < end) {free_times.add(new int[]{start, end});}}return free_times.toArray(new int[free_times.size()][]);}
employee free time
0 / 1
Phase 2
Next, we want to merge all the intervals into a single list. We can do this by iterating through the list of intervals and comparing the end time of the current interval with the start time of the next interval. If the end time of the current interval is greater than or equal to the start time of the next interval, we merge the two intervals. Otherwise, we add the current interval to the merged list.
public int[][] employeeFreeTime(int[][][] schedule) {List<int[]> flattened = new ArrayList<>();for (int[][] employee : schedule) {for (int[] interval : employee) {flattened.add(interval);}}Collections.sort(flattened, (a, b) -> a[0] - b[0]);List<int[]> merged = new ArrayList<>();for (int[] interval : flattened) {if (merged.isEmpty() || merged.get(merged.size() - 1)[1] < interval[0]) {merged.add(new int[]{interval[0], interval[1]});} else {merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], interval[1]);}}List<int[]> free_times = new ArrayList<>();for (int i = 1; i < merged.size(); i++) {int start = merged.get(i - 1)[1];int end = merged.get(i)[0];if (start < end) {free_times.add(new int[]{start, end});}}return free_times.toArray(new int[free_times.size()][]);}
merge intervals
0 / 8
Phase 3
In this phase, we return the employee free times by finding the gaps between the merged intervals. We can do this by iterating through the merged intervals, and creating a new interval from the end time of the current interval and the start time of the next interval.
public int[][] employeeFreeTime(int[][][] schedule) {List<int[]> flattened = new ArrayList<>();for (int[][] employee : schedule) {for (int[] interval : employee) {flattened.add(interval);}}Collections.sort(flattened, (a, b) -> a[0] - b[0]);List<int[]> merged = new ArrayList<>();for (int[] interval : flattened) {if (merged.isEmpty() || merged.get(merged.size() - 1)[1] < interval[0]) {merged.add(new int[]{interval[0], interval[1]});} else {merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], interval[1]);}}List<int[]> free_times = new ArrayList<>();for (int i = 1; i < merged.size(); i++) {int start = merged.get(i - 1)[1];int end = merged.get(i)[0];if (start < end) {free_times.add(new int[]{start, end});}}return free_times.toArray(new int[free_times.size()][]);}
merge
0 / 4
What is the time complexity of this solution?
O(n³)
O(n * logn)
O(n²)
O(4ⁿ)
Solution
public int[][] employeeFreeTime(int[][][] schedule) {List<int[]> flattened = new ArrayList<>();for (int[][] employee : schedule) {for (int[] interval : employee) {flattened.add(interval);}}Collections.sort(flattened, (a, b) -> a[0] - b[0]);List<int[]> merged = new ArrayList<>();for (int[] interval : flattened) {if (merged.isEmpty() || merged.get(merged.size() - 1)[1] < interval[0]) {merged.add(new int[]{interval[0], interval[1]});} else {merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], interval[1]);}}List<int[]> free_times = new ArrayList<>();for (int i = 1; i < merged.size(); i++) {int start = merged.get(i - 1)[1];int end = merged.get(i)[0];if (start < end) {free_times.add(new int[]{start, end});}}return free_times.toArray(new int[free_times.size()][]);}
employee free time
0 / 14