给出一组区间,请合并所有重叠的区间。
请保证合并后的区间按区间起点升序排列。
//"区间"定义 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.*; /* * 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; } }为什么用时这么久
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 */ // Interval类:https://wenku.baidu.com/view/48557165cf1755270722192e453610661fd95a5b.html?_wkts_=1698997239332&bdQuery=JavaInterval%E6%98%AF%E4%BB%80%E4%B9%88%E7%B1%BB&needWelcomeRecommand=1 public ArrayList<Interval> merge (ArrayList<Interval> intervals) { // write code here ArrayList<Interval> res = new ArrayList<Interval>(); if (intervals == null || intervals.size() == 0) return res; // 排序 Collections.sort(intervals, new Comparator<Interval>() { public int compare(Interval o1, Interval o2) { // 区间起始值不同 if (o1.start != o2.start) { return o1.start - o2.start; // 区间起始值相同,比较区间末尾值 } else { return o1.end - o2.end; } } }); // 初始化结果集,将intervals首元素放入结果集 res.add(intervals.get(0)); // 遍历intervals,与结果集的最后一个元素比较,如果重叠,则删除原结果集的末尾元素 // 并new出合并后的intervals,放入结果集尾部。如果不重叠,则将遍历到的区间放入结果集尾部 for (int i = 1; i < intervals.size(); i++) { // 取出结果集尾部元素 Interval i1 = res.get(res.size() - 1); // 取出遍历到的结果集 Interval i2 = intervals.get(i); // i1.end >= i2.start表示重叠, if (i1.end >= i2.start) { // 删除原结果集的末尾元素 res.remove(res.size() - 1); // new出合并后的intervals,放入结果集尾部 int star = Math.min(i1.start, i2.start); int end = Math.max(i1.end, i2.end); res.add(new Interval(star, end)); // 不重叠,则将遍历到的区间放入结果集尾部 } else res.add(i2); } return res; } }
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> sorted = new ArrayList<Interval>(); Interval last = new Interval(-1, -1); Collections.sort(intervals,new Comparator<Interval>(){ @Override public int compare(Interval i1,Interval i2){ if(i1.start-i2.start!=0){ return i1.start-i2.start; }else return i2.end-i1.end; } }); for (Interval interval : intervals) { if (last.start == -1 && last.end == -1) { last.start = interval.start; last.end = interval.end; } else if (last.start < interval.start && last.end >= interval.start) { last.end = Math.max(last.end,interval.end) ; } else if (last.end < interval.start) { sorted.add(new Interval(last.start, last.end)); last.start = interval.start; last.end = interval.end; } } if (last.start != -1 || last.end != -1) { sorted.add(last); } return sorted; } }
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 Collections.sort(intervals, new Comparator<Interval>() { public int compare(Interval a, Interval b) { if(a.start == b.start){ return a.end < b.end ? - 1 : 1; } return a.start < b.start ? - 1 : 1; } }); int i = 0, j = 1; while (j < intervals.size()) { if (intervals.get(i).end < intervals.get(j).start) { i++; j++; } else { int end = Math.max(intervals.get(i).end, intervals.get(j).end); int start = Math.min(intervals.get(i).start, intervals.get(j).start); intervals.set(i, new Interval(start, end)); intervals.remove(j); } } //Collections.sort(intervals,(Interval a,Interval b)->(a.start).compareTo(b.start)); 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) { // write code here if (intervals.size() == 0) { return intervals; } // 先排序 intervals.sort(Comparator.comparingInt(obj -> obj.start)); ArrayList<Interval> list = new ArrayList<>(); int start = intervals.get(0).start; int end = intervals.get(0).end; for (int i = 1; i < intervals.size(); i++) { Interval interval = intervals.get(i); if (end >= interval.start) { // 说明有重合 if (end < interval.end) { end = interval.end; } continue; } // 不重合 Interval tem = new Interval(start, end); list.add(tem); start = interval.start; end = interval.end; } // 最后一个 Interval tem = new Interval(start, end); list.add(tem); return list; } }