给出一组区间,请合并所有重叠的区间。
请保证合并后的区间按区间起点升序排列。
//"区间"定义
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;
}
} 为什么用时这么久