(Java)LeetCode-56. Merge Intervals

来源:互联网 发布:大数据公司被收购 编辑:程序博客网 时间:2024/06/01 08:54

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难度,看上去确实比较麻烦。最后居然AC了比较开心,虽然只打败了30%的人。

我的思路是,用两个栈 st1 st2,st1从栈底到栈顶存放的是已经处理好的,不相交的,数值递增的区间,st2是临时存储从st1.pop()出来的栈

当处理一个Interval inter的时候,将其和栈顶的区间interTop进行比较,若interTop.start大于inter.end,则说明这两个区间没有交集,就将interTop push到st2中,若有交集,则判断出交集的left 和right,把涉及到的区间丢弃,将新的interval 压入栈st1中,将st2的区间放回st1即可。代码如下:


/** * 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 List<Interval> merge(List<Interval> intervals) {        Stack<Interval> st1 = new Stack<Interval>();Stack<Interval> st2 = new Stack<Interval>();        for(Interval inter : intervals){while(!st1.isEmpty() && inter.end < st1.peek().start){st2.push(st1.pop());}if(st1.isEmpty() || inter.start > st1.peek().end){    //no crossst1.push(inter);putBack(st1,st2);continue;}if(inter.start >= st1.peek().start && inter.end <= st1.peek().end){    //fu gaiputBack(st1,st2);continue;}int right = 0, left = 0;if(inter.end > st1.peek().end){right = inter.end;}else{right = st1.peek().end;}while(!st1.isEmpty()){if(inter.start > st1.peek().end){left = inter.start;st1.push(new Interval(left, right));putBack(st1,st2);break;}else if(inter.start >= st1.peek().start){left = st1.pop().start;st1.push(new Interval(left, right));putBack(st1,st2);break;}else{st1.pop();}}if(st1.isEmpty()){left = inter.start;st1.push(new Interval(left, right));putBack(st1,st2);}}        return new ArrayList<Interval>(st1);        }        private void putBack(Stack<Interval> st1 , Stack<Interval> st2){while(!st2.isEmpty()){st1.push(st2.pop());}}}


之后在Discuss里看到一种更快的方法,首先将List中的区间按照start的大小进行排序,然后再顺序遍历一次即可。


public List<Interval> merge(List<Interval> intervals) {Collections.sort(intervals, new Comparator<Interval>(){            public int compare(Interval o1, Interval o2) {                                Interval i1 = o1;                Interval i2 = o2;                            if      (i1.start == i2.start) return 0;                else if (i1.start < i2.start)  return -1;                else                           return 1;                            }        });int left = intervals.get(0).start;int right = intervals.get(0).end;List<Interval> list = new ArrayList<Interval>();for(Interval inter : intervals){if(inter.start <= right){right = Math.max(right, inter.end);}else{list.add(new Interval(left, right));left = inter.start;right = inter.end;}}list.add(new Interval(left, right));        return list;    }


实现之后在LeetCode上发现时间并没有快很多。还有就是感觉自己的第一种想法有点异想天开啊。。

0 0