(今天码代码被导师批了,经典不务正业,一道代码题现在才写完。。。)
题目:
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
示例 :
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
思路:
这个题目思路应该还是比较明确的,先把数组按每个数组的起点从小到大排序。再比较相邻两数组前一个的数组终点和后一个数组的起点是否有重合,逐个比较即可。
具体见代码及注解。
复杂度:
时间:排序是logn,遍历是n,总复杂度在(nlogn)
空间:O(logn),排序用的空间。
代码:
public int[][] merge(int[][] intervals) {
//lamda表达式,多用来重写排序标准,比较器。必须要掌握。
//这里重写的意思就是对于intervals数组里两个数组根据他们的起点从小到大排序
Arrays.sort(intervals,(i1,i2)->i1[0]-i2[0]);
//写一个列表来存数组,即到时候重排完成的数组
List<int[]> merged = new LinkedList<>();
int i = 0;
while(i<intervals.length){
//写一个临时数组来存数组列表里的个数组
int[] temp = new int[] {intervals[i][0],intervals[i][1]};
int j = i+1;
//比较下一个数组的开头和当前数组的结尾,有重合接着比较
while(j<intervals.length && intervals[j][0]<=temp[1]){
//比较前一个数组的结尾是不是比后一个数组的结尾还大,类似[0,9],[2,5]
//temp结尾就取两个之中更大的,temp就是[0,9];
temp[1]=Math.max(temp[1],intervals[j][1]);
//j递增
j++;
}
merged.add(temp);
i=j;
}
int[][] res = new int [merged.size()][];
return merged.toArray(res);
}