Leetcode: Merge Intervals
Given a collection of intervals, merge all overlapping intervals. For example, Given [1,3],[2,6],[8,10],[15,18], return [1,6],[8,10],[15,18].
这道题跟Insert Intervals这道题很像,最开头要先对Intervals里面的Interval排序一下,用到了java的Collections.sort(List<Interval> list, Comparator<? super Interval> c)。 排序以Interval的start为第一标准,从小到大,如果start一样的情况下,才以end作为第二标准。这样排序的好处是,简化了接下来处理的难度。
我们只需要把intervals里的interval依次添加到结果集合里,每次将要添加时,只需要判断当前这个interval的start跟结果集合里面最后一个Interval的end谁大,如果结果集合里面最后一个Interval的end大,说明overlap了,需要改一下这个end就好了,否则没有Overlap,直接添加该Interval进结果集合里就好了。
sort的好处是,只用管end,不用管start, 因为新添加的Interval的start至少是大于等于结果集合里面已经添加的Interval的start的。换言之,start不受影响,简化了我们的处理。
所以本问题的关键在于给Intervals排序,可以用java的Collections.sort(List<Interval> list, Comparator<? super Interval> c)。因为Interval是我们自己定义的,所以我们也需要自己定义Comparator,而不能用默认的。我们可以写一个我们自己的Comparator来override默认的。规则是按起始点排序,然后如果起始点相同就按结束点排序。整个算法是先排序,然后再做一次线性遍历,时间复杂度是O(nlogn+n)=O(nlogn),空间复杂度是O(1),因为不需要额外空间,只有结果集的空间。
Output is an array:
Syntax:
1. Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1[0], i2[0]));
2. list.toArray(new int[list.size()][2]);
1 class Solution { 2 public int[][] merge(int[][] intervals) { 3 if (intervals == null || intervals.length == 0 || intervals[0].length == 0) return new int[][]{}; 4 List<int[]> list = new ArrayList<int[]>(); 5 6 Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1[0], i2[0])); 7 8 list.add(intervals[0]); 9 int i = 1; 10 while (i < intervals.length) { 11 int[] last = list.get(list.size() - 1); 12 if (intervals[i][0] <= last[1]) { 13 last[1] = Math.max(last[1], intervals[i][1]); 14 } 15 else { 16 list.add(intervals[i]); 17 } 18 i ++; 19 } 20 21 return list.toArray(new int[list.size()][2]); 22 } 23 }
Output is a list
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 public class Solution { 11 public List<Interval> merge(List<Interval> intervals) { 12 ArrayList<Interval> res = new ArrayList<Interval>(); 13 if (intervals == null || intervals.size() == 0) { 14 return intervals; 15 } 16 Comparator<Interval> comp = new Comparator<Interval>() { 17 public int compare(Interval t1, Interval t2) { 18 if (t1.start == t2.start) { 19 return t1.end - t2.end; 20 } 21 return t1.start - t2.start; 22 } 23 }; 24 Collections.sort(intervals, comp); 25 res.add(intervals.get(0)); 26 for (int i=1; i<intervals.size(); i++) { 27 if (res.get(res.size()-1).end >= intervals.get(i).start) { 28 res.get(res.size()-1).end = Math.max(res.get(res.size()-1).end, intervals.get(i).end); 29 } 30 else { 31 res.add(intervals.get(i)); 32 } 33 } 34 return res; 35 } 36 }