[关闭]
@xmruibi 2015-04-04T15:06:09.000000Z 字数 2128 阅读 805

Interval Problems

Algorithm


关于interval数组结构的操作,在面试中也是一种比较常见的数据结构.

  1. class Interval {
  2. int start;
  3. int end;
  4. Interval() {
  5. start = 0;
  6. end = 0;
  7. }
  8. Interval(int s, int e) {
  9. start = s;
  10. end = e;
  11. }
  12. }

此类题型 需要注意时间空间复杂度说明。
1. Merge Intervals
假设这些interval是有序的(也就是说先按起始点排序,然后如果起始点相同就按结束点排序),那么要把它们合并就只需要按顺序读过来,如果当前一个和结果集中最后一个有重叠,那么就把结果集中最后一个元素设为当前元素的结束点(不用改变起始点因为起始点有序,因为结果集中最后一个元素起始点已经比当前元素小了)。那么剩下的问题就是如何给interval排序,在java实现中就是要给interval自定义一个Comparator,规则是按起始点排序,然后如果起始点相同就按结束点排序。

  1. public List<Interval> merge(List<Interval> intervals) {
  2. // notice this intervals list is not sorted!!
  3. /**整个算法是先排序,然后再做一次线性遍历,时间复杂度是O(nlogn+n)=O(nlogn),空间复杂度是O(1),因为不需要额外空间,只有结果集的空间。**/
  4. List<Interval> res = new ArrayList<Interval>();
  5. if(intervals==null||intervals.size()==0)
  6. return res;
  7. Collections.sort(intervals, new Comparator<Interval>() {
  8. @Override
  9. public int compare(Interval o1, Interval o2) {
  10. return Integer.compare(o1.start, o2.start);
  11. }
  12. });
  13. res.add(intervals.get(0));
  14. for(int i=1;i<intervals.size();i++){
  15. int start = res.get(res.size()-1).start;
  16. int end = res.get(res.size()-1).end;
  17. if(intervals.get(i).start>end){
  18. res.add(intervals.get(i));
  19. }else if(intervals.get(i).end<start){
  20. res.add(res.size()-1,intervals.get(i));
  21. }else{
  22. start = Math.min(start, intervals.get(i).start);
  23. end = Math.max(end, intervals.get(i).end);
  24. res.set(res.size()-1, new Interval(start,end));
  25. }
  26. }
  27. return res;
  28. }
  1. Insert Intervals
    这道题不需要排序,因为插入之前已经默认这些intervals排好序了。简单一些的是这里最多只有一个连续串出现冲突,因为就插入那么一个。基本思路就是先扫描走到新的interval应该插入的位置,接下来就是插入新的interval并检查后面是否冲突,一直到新的interval的end小于下一个interval的start,然后取新interval和当前interval中end大的即可。因为要进行一次线性扫描,所以时间复杂度是O(n)。而空间上如果我们重新创建一个ArrayList返回,那么就是O(n)。(为什么不in-place的进行操作,这样就不需要额外空间,但是如果使用ArrayList这个数据结构,那么删除操作是线性的,如此时间就不是O(n)的。如果这道题是用LinkedList那么是可以做到in-place的,并且时间是线性的。)
  1. public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
  2. List<Interval> res = new ArrayList<Interval>();
  3. res.add(newInterval);
  4. if(intervals==null)
  5. return res;
  6. for(Interval interval:intervals){
  7. int start = res.get(res.size()-1).start;
  8. int end = res.get(res.size()-1).end;
  9. if(start>interval.end)
  10. res.add(res.size()-1, interval);
  11. else if(end<interval.start)
  12. res.add(interval);
  13. else{
  14. start = Math.min(start, interval.start);
  15. end = Math.max(end, interval.end);
  16. res.set(res.size()-1, new Interval(start, end));
  17. }
  18. }
  19. return res;
  20. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注