IT技术小屋

秋风秋雨,皆入我心

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  38 随笔 :: 1 文章 :: 19 评论 :: 0 Trackbacks
1、给定一组区间,表示为[start,end],请给出方法,将有重叠的区间进行合并。例如:
给定:[1,3],[2,6],[8,10],[15,18],
合并:[1,6],[8,10],[15,18].
分析:题目很直观,首先把区间递增排序,然后从头合并,合并时观察当前区间的start是否小于或等于前一个区间的end。代码如下:
 1 public class MergeIntervals {
 2     public class IntervalCmp implements Comparator<Interval> {
 3         @Override
 4         public int compare(Interval i1, Interval i2) {
 5             if (i1.start < i2.start) return -1;
 6             if (i1.start == i2.start && i1.end <= i2.end) return -1;
 7             return 1;
 8         }
 9     }
10     
11     public ArrayList<Interval> merge(ArrayList<Interval> intervals) {
12         ArrayList<Interval> ret = new ArrayList<Interval>();
13         if (intervals.size() == 0) return ret;
14         Interval[] arr = new Interval[intervals.size()];
15         intervals.toArray(arr);
16         Arrays.sort(arr, new IntervalCmp());
17         int start = arr[0].start;
18         int end = arr[0].end;
19         for (int i = 0; i < arr.length; i++) {
20             if (arr[i].start <= end) {
21                 end = Math.max(end, arr[i].end);
22             } else {
23                 ret.add(new Interval(start, end));
24                 start = arr[i].start;
25                 end = arr[i].end;
26             }
27         }
28         ret.add(new Interval(start, end));
29         return ret;
30     }
31 }
2、给定的一组区间,将区间中的存在的任意区间的父区间删除,例如:
给定:[1,2] [1,3] [1,4] [5,9] [6,8]
删除后:[1,2] [6,8]
分析:此题暴力的解法的复杂度为O(N^2)。受上一题排序的启发,是否有好一点的思路呢?
我们可以按照start递增排序,若start相等,则按照end递减排序。考虑排序后的第i-1 和第i个区间,由于start是递增的,所以第i-1个区间的start肯定小于等于第i个区间的start。若第i-1个区间的end大于等于第i个区间的end,则第i-1个区间就成为第i个区间的父区间了。

按照这个思路,可以试着在排序之后逆向顺序处理每一个区间。假设当前处理第i个区间,如前所述,若第i-1个区间的end大于等于第i个区间的end,则第i-1个区间成为第i个区间的父区间,可以保留第i个区间,将第i-1个区间删除。由于第i-1个区间是第i个区间的父区间,所以第i-1个区间的父区间也是第i个区间的父区间,这种情形下删掉第i-1个区间,后续不会漏删第i-1个区间的父区间。若第i-1个区间的end小于第i个区间的end,则可以跳过第i个区间,开始处理第i-1个区间。因为按照这种处理的方法,在处理到第i个区间时,该区间不会是任何区间的父区间(若是父区间已经被如前所述的方法删除了)。而且,在这种情形下,后续可能出现的第i个区间的父区间会是第i-1个区间的父区间,所以也不会漏掉第i个区间的父区间。所以排序之后逆向处理,只需要O(N)的时间,就可以解决这道问题。整体的时间复杂度为O(nlogn)。
 1 public class Solution {
 2     public class IntervalCmp implements Comparator<Interval> {
 3         @Override
 4         public int compare(Interval i1, Interval i2) {
 5             if (i1.start < i2.start) return -1;
 6             if (i1.start == i2.start && i1.end >= i2.end) return -1;
 7             return 1;
 8         }
 9     }
10     
11     public ArrayList<Interval> merge(ArrayList<Interval> intervals) {
12         ArrayList<Interval> ret = new ArrayList<Interval>();
13         if (intervals.size() == 0) return ret;
14         Interval[] arr = new Interval[intervals.size()];
15         intervals.toArray(arr);
16         Arrays.sort(arr, new IntervalCmp());
17         int start = arr[arr.length - 1].start;
18         int end = arr[arr.length - 1].end;
19         for (int i = arr.length - 2; i >= 0; i--) {
20             if (arr[i].end < end) {
21                 ret.add(new Interval(start, end));
22                 start = arr[i].start;
23                 end = arr[i].end;
24             }
25         }
26         ret.add(new Interval(start, end));
27         return ret;
28     }
29 }
posted on 2013-12-26 14:47 Meng Lee 阅读(1776) 评论(0)  编辑  收藏 所属分类: Leetcode

只有注册用户登录后才能发表评论。


网站导航: