Merge Intervals

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;

    }

}

 

你可能感兴趣的:(merge)