Idiot-maker

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

https://leetcode.com/problems/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].

解题思路:

这题应该没有hard的难度。思路如下:

1. 对原intervals的List根据start排序。

2. 遍历intervals,如果当前interval的start<=前一个interval的end,就合并它们,即将start设置为前一个interval的start,end设置为两者较大的。合并的结果作为前一个interval保存。否则,将前一个interval塞进结果list,当前前一个interval作为前一个interval保存。

3. 重复第2步,直至intervals结束。

还有些边界条件需要考虑,比如遍历到intervals的最后一个元素,无论合并与否,都要将结果加入到result里。

先使用了优先队列,也就是最小堆,占用了额外的O(n)空间。

/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */
public class Solution {
    public class Compare implements Comparator<Interval> {
        public int compare(Interval l1, Interval l2){
            return l1.start - l2.start;
        }
    }
    
    public List<Interval> merge(List<Interval> intervals) {
        List<Interval> result = new ArrayList<Interval>();
        if(intervals == null || intervals.size() == 0) {
            return result;
        }
        PriorityQueue<Interval> queue = new PriorityQueue<Interval>(intervals.size(), new Compare());
        for(int i = 0; i < intervals.size(); i++){
            queue.add(intervals.get(i));
        }
        
        Interval current = null;
        Interval previous = null;
        while(queue.size() > 0){
            current = queue.poll();
            if(previous == null) {
                previous = current;
                if(queue.size() == 0) {
                    result.add(previous);
                }
                continue;
            }
            if(current.start > previous.end) {
                result.add(previous);
                previous = current;
            } else {
                current.start = previous.start;
                current.end = Math.max(current.end, previous.end);
                previous = current;
            }
            if(queue.size() == 0) {
                result.add(previous);
            }
        }
        
        return result;
    }
}

后来感觉可以针对intervals排序,不用额外空间了。

/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */
public class Solution {
    public class Compare implements Comparator<Interval> {
        public int compare(Interval l1, Interval l2){
            return l1.start - l2.start;
        }
    }
    
    public List<Interval> merge(List<Interval> intervals) {
        List<Interval> result = new ArrayList<Interval>();
        if(intervals == null || intervals.size() == 0) {
            return result;
        }
        
        Collections.sort(intervals, new Compare());
        
        Interval current = null;
        Interval previous = null;
        for(int i = 0; i < intervals.size(); i++) {
            current = intervals.get(i);
            if(previous == null) {
                previous = current;
                if(i == intervals.size() - 1) {
                    result.add(previous);
                }
                continue;
            }
            if(current.start > previous.end) {
                result.add(previous);
                previous = current;
            } else {
                current.start = previous.start;
                current.end = Math.max(current.end, previous.end);
                previous = current;
            }
            if(i == intervals.size() - 1) {
                result.add(previous);
            }
        }
        return result;
    }
}

不管如何,时间复杂度都是O(n*logn),排序所花。

update 2015/05/21:

二刷。以前的思路很混乱啊。写了一个简单点的。

/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */
public class Solution {
    public class Compare implements Comparator<Interval> {
        public int compare(Interval i1, Interval i2) {
            return i1.start - i2.start;
        }
    }
    public List<Interval> merge(List<Interval> intervals) {
        List<Interval> result = new ArrayList<Interval>();
        if(intervals == null || intervals.size() == 0 || intervals.size() == 1) {
            return intervals;
        }
        Collections.sort(intervals, new Compare());
        Interval pre = intervals.get(0);
        Interval merge = null;
        for(int i = 1; i < intervals.size(); i++) {
            Interval cur = intervals.get(i);
            if(cur.start > pre.end) {
                result.add(pre);
                pre = cur;
            } else {
                pre.end = Math.max(pre.end, cur.end);
            }
            if(i == intervals.size() - 1) {
                if(pre == cur) {
                    result.add(cur);
                } else {
                    pre.end = Math.max(pre.end, cur.end);
                    result.add(pre);
                }
            }
        }
        return result;
    }
}

其实还有更简单的。直接比较结果集result中的最后一个interval——last和当前interva——cur。如果last.end>=cur.start,于是last.end = max(last.end, cur.end),否则就将cur加入result。

这个代码最为简单,思路也最为清晰。

/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */
public class Solution {
    public class Compare implements Comparator<Interval> {
        public int compare(Interval i1, Interval i2) {
            return i1.start - i2.start;
        }
    }
    public List<Interval> merge(List<Interval> intervals) {
        List<Interval> result = new ArrayList<Interval>();
        if(intervals == null || intervals.size() == 0 || intervals.size() == 1) {
            return intervals;
        }
        Collections.sort(intervals, new Compare());
        result.add(intervals.get(0));
        for(int i = 1; i < intervals.size(); i++) {
            Interval cur = intervals.get(i);
            Interval lastResult = result.get(result.size() - 1);
            if(lastResult.end >= cur.start) {
                lastResult.end = Math.max(lastResult.end, cur.end);
            } else {
                result.add(cur);
            }
        }
        return result;
    }
}

 

posted on 2015-04-02 16:54  NickyYe  阅读(263)  评论(0编辑  收藏  举报