例子:
合并区间,主要考虑需要合并区间的左边和右边。通过循环遍历时,维护两个值,分不同情况进行判断:
情况1
以区间 [ 1 , 3 ] [1,3] [1,3] 和区间 [ 2 , 4 ] [2,4] [2,4] 为例,区间 [ 1 , 3 ] [1,3] [1,3] 的右边界大于区间 [ 2 , 4 ] [2,4] [2,4] 的左边界,则需要将两个区间合并,合并之后的区间为: [ 1 , 4 ] [1,4] [1,4]
以区间 [ 1 , 4 ] [1,4] [1,4] 和区间 [ 2 , 3 ] [2,3] [2,3] 为例,区间 [ 1 , 4 ] [1,4] [1,4] 的右边界大于区间 [ 2 , 3 ] [2,3] [2,3] 的左边界,则需要将两个区间合并,合并之后的区间为: [ 1 , 4 ] [1,4] [1,4]
因此可以得出,两个区间的合并需要考虑:
- 两个区间是否相交
- 区间的右端点应该为两个区间右端点的最大值
通过循环时考虑边界条件,可得到如下代码:
class Solution {
public int[][] merge(int[][] intervals) {
if (intervals.length == 1) return intervals;
Arrays.sort(intervals, (a, b) -> {
if(a[0]==b[0]) return a[1]-b[1];
return a[0]-b[0];
});
ArrayList<int[]> arrayList = new ArrayList<>();
int i = 0, j = 1;
it:while (j < intervals.length) {
int behind = intervals[i][1];
int before = intervals[j][0];
while (behind >= before) {
behind = Math.max(behind, intervals[j][1]);
if (j == intervals.length - 1) {
arrayList.add(new int[]{intervals[i][0], behind});
break it;
}
j++;
before = intervals[j][0];
}
if (behind < before) {
arrayList.add(new int[]{intervals[i][0], behind});
i = j;
j++;
if (j == intervals.length) arrayList.add(intervals[j - 1]);
}
}
return arrayList.toArray(new int[arrayList.size()][]);
}
}
p s : ps: ps: 看了一下官解,觉得它的思想更简单,通过维护链表中的数组来不断更新链表,贴一下官解代码:
class Solution {
public int[][] merge(int[][] intervals) {
if (intervals.length == 1) return intervals;
Arrays.sort(intervals, (a, b) -> {
if(a[0]==b[0]) return a[1]-b[1];
return a[0]-b[0];
});
ArrayList<int[]> arrayList = new ArrayList<>();
for(int i=0;i<intervals.length;i++){
int L = intervals[i][0] , R = intervals[i][1];
if(arrayList.size()==0 || arrayList.get(arrayList.size()-1)[1]<L){
arrayList.add(new int[]{L,R});
}else {
arrayList.get(arrayList.size()-1)[1]=
Math.max(arrayList.get(arrayList.size()-1)[1],R);
}
}
return arrayList.toArray(new int[arrayList.size()][]);
}
}