leetcode中区间相关问题
- q56 合并区间
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
初次思考,因为我在这里看了官方的样例,犯了想当然的错误认为给的二维数组里面的每个数组的区间都是已经排好序的。(这里暂且把二维数组看作一个矩阵)于是直接循环每行,让其最后一列的数和下一列的第一个数比较,如果小于等于,则合并,并把两行合并成一行。然后继续循环。
看了看别人的思路,首先按照每行的首列数字大小排序,即
Arrays.sort(intervals, (v1, v2) -> v1[0] - v2[0]);
上述代码:假设传来两个值,v1 与 v2,那么他们的先后顺序以 v1[0] 比 v2[0] 的结果为准,即:若 v1[0] < v2[0] 则 v1 < v2,若 = 则 =,若 > 则 >。实际上这里是对矩阵的每一行重新排列。
排列完毕以后,我们得到了一个有序的首列数字升序(也可能相等)的矩阵。
然后设置变量index,
int[][] res = new int[intervals.length][2];
int idx = -1;
// 依次取出一维数组进行遍历
for (int[] interval: intervals) {
// 如果结果数组是空的,或者当前区间的起始位置 > 结果数组中最后区间的终止位置,
// 则不合并,直接将当前区间加入结果数组。
if (idx == -1 || interval[0] > res[idx][1]) {
res[++idx] = interval;
} else {
// 反之将当前区间合并至结果数组的最后区间
res[idx][1] = Math.max(res[idx][1], interval[1]);
}
}
最后返回Arrays.copyOf(res,index+1);即可
- q57 合并区间
题目描述:给你一个无重叠的,按照区间起始端点排序的区间列表。在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。
这道题和56题的区别在于,区间列表已经有序,我们需要在有序的列表里面插入一个新的区间,并且可以合并。
那么我们是否可以这样想,新区间肯定是在区间列表里面某个范围的,首先我们需要将列表区间左侧且和新区间相隔离的加入新的列表集,然后找到列表区间和新区间有重叠的部分,必要时可以合并,加入新列表集,最后找到列表右侧和新区间隔离的部分,并将它们加入新列表集。
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
//定义结果集res,这里注意长度
int[][] res=new int[intervals.length+1][2];
int idx=0;
int i=0;
//遍历区间,如果intervals[i][1]<newInterval[0],说明左区间和新区间并无交集,加入结果集;
while(i<intervals.length&&intervals[i][1]<newInterval[0]){
res[idx++]=intervals[i++];
}
//否则的话,只要intervals[i][0]<=newInterval[1],就说明仍然有交集,合并,i+1;再次判断,
// 将新区间加入结果集
while(i<intervals.length&&intervals[i][0]<=newInterval[1]){
newInterval[0]=Math.min(intervals[i][0],newInterval[0]);
newInterval[1]=Math.max(intervals[i][1],newInterval[1]);
i++;
}
res[idx++]=newInterval;
//将右边且相离的区间加入结果集
while(i<intervals.length){
res[idx++]=intervals[i++];
}
return Arrays.copyOf(res,idx);
}
}

浙公网安备 33010602011771号