package com.freetymekiyan.algorithms.level.hard; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Given a collection of intervals, merge all overlapping intervals. * <p> * For example, * Given [1,3],[2,6],[8,10],[15,18], * return [1,6],[8,10],[15,18]. * <p> * Company Tags: LinkedIn, Google, Facebook, Twitter, Microsoft, Bloomberg, Yelp * Tags: Array, Sort * Similar Problems: (H) Insert Interval, (E) Meeting Rooms, (M) Meeting Rooms II */ public class MergeIntervals { /** * Sort. O(nlogn) Time. * Sort the intervals by start time, ascending. * Use a pointer, prev, for previous merged interval. * For each of the intervals: * | If prev == null, merged is empty, add directly and update prev. * | If prev.end < i.start, no overlap, add directly and update prev. * | Else if prev.end >= i.start, there is overlap. * | We already know i.start >= prev.start because of sorting. No need to update start. * | Only update end is enough. * | If prev.end >= i.end, no need to update end. * | If prev.end < i.end, update end to i.end. */ public List<Interval> merge(List<Interval> intervals) { if (intervals == null || intervals.size() <= 1) { return intervals; } List<Interval> merged = new ArrayList<>(); Collections.sort(intervals, (i1, i2) -> Integer.compare(i1.start, i2.start)); Interval prev = null; // A pointer to the last interval in merged list. for (Interval i : intervals) { if (prev == null || prev.end < i.start) { // Empty list or no overlap. merged.add(i); prev = i; // Update previous pointer. } else if (prev.end < i.end) { // Overlap and the end of current interval is larger. prev.end = i.end; // Update previous end to merge. } } return merged; } /** * Interval class provided by leetcode. */ public class Interval { int start; int end; Interval() { start = 0; end = 0; } Interval(int s, int e) { start = s; end = e; } } }