给出一组区间,请合并所有重叠的区间。
	请保证合并后的区间按区间起点升序排列。
//"区间"定义
class Interval {
   int start; //起点
   int end;   //终点
}
	数据范围:区间组数 
,区间内 的值都满足 
 
	要求:空间复杂度 
,时间复杂度 
 
	进阶:空间复杂度 
,时间复杂度
 
                                        //"区间"定义
class Interval {
   int start; //起点
   int end;   //终点
}
[[10,30],[20,60],[80,100],[150,180]]
[[10,60],[80,100],[150,180]]
[[0,10],[10,20]]
[[0,20]]
import java.util.*;
import java.util.stream.*;
public class Solution {
    public ArrayList<Interval> merge (ArrayList<Interval> intervals) {
        intervals = (ArrayList) intervals.stream().sorted((a,b)->a.start - b.start)
            .collect(Collectors.toList());
        int point = 0;
        while (point < intervals.size() - 1) {
            Interval val1 = (Interval) intervals.get(point);
            Interval val2 = (Interval) intervals.get(point + 1);
            if (val1.end >= val2.start) {
                intervals.remove(point);
                intervals.set(point, new Interval(val1.start, Math.max(val1.end, val2.end)));
                continue;
            }
            point++;
        }
        return intervals;
    }
}  public ArrayList<Interval> merge (ArrayList<Interval> intervals) {
        /**
            使用排序加贪心
            先将所有的 interval 按照 start的顺序开始排序
            之后先把第一个interval 放到 ans数组中 记 res
            之后在比较后续的interval 记 next
            if res.end < next.start
               ans.add(next)
             else  合并
              ans.remove(res);
              if(res.end < next.end)
               new res.start,next.end
              res.start,res.end;
         */
        if (intervals.size() == 0) {
            return new ArrayList<>();
        }
        // 按照区间的起始位置进行排序
        Collections.sort(intervals, new Comparator<Interval>() {
            public int compare(Interval o1, Interval o2) {
                return o1.start - o2.start;
            }
        });
        ArrayList<Interval> ans = new ArrayList<>();
        ans.add(intervals.get(0));
        for (int i = 1; i < intervals.size(); i++) {
            Interval res = ans.get(ans.size() - 1);
            Interval next = intervals.get(i);
            if (res.end < next.start) {
                ans.add(next);
            } else {
                res.end = Math.max(res.end, next.end);
            }
        }
        return ans;
    } import java.util.*;
/*
 * public class Interval {
 *   int start;
 *   int end;
 *   public Interval(int start, int end) {
 *     this.start = start;
 *     this.end = end;
 *   }
 * }
 */
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param intervals Interval类ArrayList
     * @return Interval类ArrayList
     */
    public ArrayList<Interval> merge (ArrayList<Interval> intervals) {
        // write code here
        int max = 0;
        for (Interval i : intervals) {
            max = i.end > max ? i.end : max;
        }
        boolean[] arr = new boolean[max + 1];
        Arrays.fill(arr, false);
        for (Interval i : intervals) {
            Arrays.fill(arr, i.start, i.end, true);
        }
        // 重新构造区间
        // 区间开闭信号
        boolean flag = false;
        Interval inv = new Interval(0, 0);
        ArrayList<Interval> res = new ArrayList<Interval>();
        for (int i = 0; i < max + 1; i++) {
            if (!flag) {
                // 等待一个区间开始信号
                if (arr[i]) {
                    inv.start = i;
                    flag = true;
                    continue;
                }
            } else {
                // 等待一个闭区间信号
                if (!arr[i]) {
                    inv.end = i;
                    flag = false;
                    res.add(inv);
                    inv = new Interval(0, 0);
                    continue;
                }
            }
        }
        // 有一种情况是循环到了最后一位,区间还没关闭,得判断一下
        if (flag) {
            inv.end = max;
            flag = false;
            res.add(inv);
        }
        return res;
    }
}  /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param intervals Interval类ArrayList 
     * @return Interval类ArrayList
     */
    public ArrayList<Interval> merge (ArrayList<Interval> intervals) {
        if(intervals.size()<=1)
            return intervals;
        intervals.sort((a,b)->a.start-b.start);
        int start = intervals.get(0).start;
        int end = intervals.get(0).end;
        ArrayList<Interval> answer = new ArrayList<Interval>();
        for(int i=1;i<intervals.size();i++){
            if(intervals.get(i).start>=start&&intervals.get(i).start<=end){
                end = Math.max(end,intervals.get(i).end);
            }else{
                answer.add(new Interval(start,end));
                start = intervals.get(i).start;
                end = intervals.get(i).end;
            }
        }
        answer.add(new Interval(start,end));
        return answer;
    } 进阶版的时间和空间复杂度,让我猜测是不是应该这么写     /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param intervals Interval类ArrayList
     * @return Interval类ArrayList
     */
    public ArrayList<Interval> merge (ArrayList<Interval> intervals) {
        if (intervals.size() <= 1)
            return intervals;
        //找到最大的起始start位置,时间复杂度O(n)
        int max = intervals.get(0).start;
        for (int i = 1; i < intervals.size(); i++) {
            if (intervals.get(i).start > max) {
                max = intervals.get(i).start;
            }
        }
        ArrayList<Interval> answer = new ArrayList<Interval>();
        //生成0-max大小的区间,对应数字代表区间的长度
        int[] length = new int[max + 1]; //空间复杂度O(val)
        //时间复杂度O(n)
        for (int i = 0; i < intervals.size(); i++) {
            int len = intervals.get(i).end - intervals.get(i).start + 1; //记录区间长度
            if (length[intervals.get(i).start] != 0) { //当前已经有区间
                length[intervals.get(i).start] = Math.max(len, length[intervals.get(i).start]);
            } else {
                length[intervals.get(i).start] = len;
            }
        }
        //添加区间
        int start = -1;
        int end = -2;
        //时间复杂度O(val)
        for (int i = 0; i < max+1; i++) {
            if(end>=0&&i>end){ //找到一个完整的区间了
                answer.add(new Interval(start,end));
                start = -1;
                end =  -2;
            }
            if(length[i]!=0){ //当前有区间
                if(start==-1){ //没有包含区间
                    start = i;
                    end = length[i]+i-1;
                }else{
                    end = Math.max(end,length[i]+i-1); //合并区间
                }
            }
        }
        answer.add(new Interval(start, end));
        return answer;
    } public class Solution {
    public ArrayList<Interval> merge (ArrayList<Interval> intervals) {
        if (intervals.size() <= 1) return intervals;
        Collections.sort(intervals, (a, b)-> {
            return a.start <= b.start ? -1 : 1;
        });
        ArrayList<Interval> res = new ArrayList<Interval>();
        res.add(intervals.get(0));
        for (int i = 1; i < intervals.size(); i++) {
            if (res.get(res.size() - 1).end >= intervals.get(i).start) {
                res.get(res.size() - 1).end = Math.max(intervals.get(i).end,res.get(res.size() - 1).end);
            } else res.add(intervals.get(i));
        }
        return res;
    }
} 
                                                                                    public ArrayList<Interval> merge (ArrayList<Interval> intervals) {
        // 根据start进行从小到大排序, 将start end 2个影响因素降为1个
        intervals.sort((a, b) -> a.start - b.start);
        ArrayList<Interval> resList = new ArrayList<>();
        // 数组为空, 或者长度为1直接返回
        if (intervals.size() < 2) {
            return intervals;
        }
        // 双指针左指针
        Interval pre = intervals.get(0);
        resList.add(pre);
        for (int i = 1; i < intervals.size(); i++) {
            // 双指针右指针
           Interval curr = intervals.get(i);
           // 有合二为一的情况。设置合并后的右区间
           if (curr.start >= pre.start && curr.start <= pre.end) {
              pre.end = curr.end >= pre.end ? curr.end : pre.end;
              // 无合并情况, 直接添加, 并且左指针后移
           } else {
              resList.add(curr);
              pre = curr;
           }
        }
        return resList;
    } public ArrayList<Interval> merge(ArrayList<Interval> intervals) {
        // write code here
        if (intervals.size() <= 1) {
            return intervals;
        }
        int maxLength = 200001;
        int[] lengthArray = new int[maxLength];
        for (Interval interval : intervals) {
            lengthArray[interval.start] = Math.max(interval.end - interval.start + 1, lengthArray[interval.start]);
        }
        int startPos = -1;
        int length = -1;
        ArrayList<Interval> resultList = new ArrayList<>();
        for (int i = 0; i < maxLength; i++) {
            if (length > 0) {
                length--;
                if (length == 0) {
                    resultList.add(new Interval(startPos, i - 1));
                    length = -1;
                    startPos = -1;
                }
            }
            if (length > 0 && lengthArray[i] > 0) {
                length = Math.max(length, lengthArray[i]);
            } else if (length == -1 && lengthArray[i] > 0) {
                startPos = i;
                length = lengthArray[i];
            }
        }
        return resultList;
    } public ArrayList<Interval> merge (ArrayList<Interval> intervals) {
    // write code here
    PriorityQueue<Interval> queue=new PriorityQueue<>(new Comparator<Interval>(){
        @Override
        public int compare(Interval i1 ,Interval i2){
            if(i1.start==i2.start){
                return i1.end-i2.end;
            }else{
                return i1.start-i2.start;
            }
        }
    });
    for(Interval i:intervals){
        queue.add(i);
    }
    ArrayList<Interval> res=new ArrayList<>();
    while(!queue.isEmpty()){
        Interval interval=queue.poll();
        while(!queue.isEmpty() && queue.peek().start<=interval.end){
            interval.end=Math.max(interval.end ,queue.poll().end);
        }
        res.add(interval);
    }
    return res;
} public class Solution {
    public ArrayList<Interval> merge (ArrayList<Interval> intervals) {
        Collections.sort(intervals, new Comparator<Interval>() {
            @Override
            public int compare(Interval o1, Interval o2) {
                return o1.start - o2.start;
            }
        });
        for (int i = 0; i < intervals.size() - 1; i++) {
            Interval cur = intervals.get(i);
            Interval next = intervals.get(i + 1);
            if (next.start <= cur.end) {
                if (next.end <= cur.end) {
                    intervals.remove(i + 1);
                    i--;
                } else {
                    cur.end = next.end;
                    intervals.remove(i + 1);
                    i--;
                }
            }
        }
        return intervals;
    }
} import java.util.*;
/*
 * public class Interval {
 *   int start;
 *   int end;
 *   public Interval(int start, int end) {
 *     this.start = start;
 *     this.end = end;
 *   }
 * }
 */
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param intervals Interval类ArrayList 
     * @return Interval类ArrayList
     */
    public ArrayList<Interval> merge (ArrayList<Interval> intervals) {
        if (intervals.isEmpty()) return new ArrayList<>();
        intervals.sort((o1, o2) -> o1.start - o2.start);
        Iterator<Interval> ite = intervals.iterator();
        Interval prev = ite.next();
        while (ite.hasNext()) {
            Interval next = ite.next();
            if (prev.end >= next.start) {
                if (prev.end >= next.end) {
                    ite.remove();
                } else {
                    prev.end = next.end;
                    ite.remove();
                }
            } else {
                prev = next;
            }
        }  
        return intervals;
    }
} 迭代器解法,感觉比别人的更好理解,利用了 Java 8 迭代器中 remove 的方法,同时储存prev和next,不用考虑循环的索引问题。
                                                                                    public class Solution {
    public ArrayList<Interval> merge(ArrayList<Interval> intervals) {
        if (intervals == null || intervals.size() < 2) {
            return intervals;
        }
        Collections.sort(intervals, new Comparator<Interval>() {
            @Override
            public int compare(Interval o1, Interval o2) {
                return o1.start - o2.start;
            }
        });
        ArrayList<Interval> newList = new ArrayList<>();
        Interval prev = intervals.get(0);// 上一个需要合并的
        int index = 1;
        while (index < intervals.size()) {
            Interval current = intervals.get(index);// 得到当前的节点,
            //用当前节点和上一节点做对比
            if (prev.end >= current.start) {
                //重叠,需要合并,更新上一节点,否则不用更新,维持prev,继续向后遍历
                if (prev.end < current.end) {
                    prev.end = current.end;
                }
            } else {
                // 不重叠,那么添加上一节点
                newList.add(prev);
                prev = current;
            }
            index ++;
        }
        newList.add(prev);
        return newList;
    }
} import java.util.*;
/*
 * public class Interval {
 *   int start;
 *   int end;
 *   public Interval(int start, int end) {
 *     this.start = start;
 *     this.end = end;
 *   }
 * }
 */
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param intervals Interval类ArrayList 
     * @return Interval类ArrayList
     */
    public ArrayList<Interval> merge (ArrayList<Interval> intervals) {
        // write code here
        ArrayList<Interval> newIntervals = new ArrayList<>();
        Collections.sort(intervals, (a, b) -> a.start - b.start);
        int len = intervals.size();
        for(int i = 0; i < intervals.size(); i++){
            Interval node = new Interval(intervals.get(i).start, intervals.get(i).end);
            while(i < len - 1){
                i++;
                if(intervals.get(i).start <= node.end && intervals.get(i).end > node.end){
                    node.end = intervals.get(i).end;
                }else if(intervals.get(i).start > node.end){
                    i--;
                    break;
                }
            }
            newIntervals.add(node);
        }
        return newIntervals;
    }
} 为什么用时这么久