【LeetCode】合并区间 (排序)
给出一个区间的集合,请合并所有重叠的区间。
示例 1:
输入: intervals = [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例2:
输入: intervals = [[30,80],[1,15],[1,100]]
输出: [[1,100]]
解释: 这个数组中的其它区间都在1与100之间.
提示:
intervals[i][0] <= intervals[i][1]
解题思路如下:
- 先对二维数组按照区间左边的值进行升序排列(二维数组按行排序)
- 对排好序的二维数组intervals进行合并去重叠,逻辑如下:
因为排好了序intervals的第0行0列直接加入到list中。maxValue进行记录当前右边最大值(也就是intervals[i][1]),如果maxValue值小于下行左值,maxValue与下行左值可直接加入list,更新maxValue为下行右值。如果maxValue值大于或等于下行左值,须判断maxValue如果小于下行右值,则maxValue被赋值为下行右值,否则返回对下下行进行判断。
如图:
都是用当前的右值(maxValue)去对下行的左值与右值进行判断!
画图能使问题更直观! 分解拆分问题,第一步是对第二步的铺垫,先如何后如何。
代码如下:
public static int[][] merge(int[][] intervals) {
if(intervals==null||intervals.length==0)
return new int[0][0];
//1.排序
Arrays.sort(intervals, new Comparator<int[]>(){
@Override
public int compare(int[] o1, int[] o2)
{ return o1[0] - o2[0];}
});
//2.合并重叠
List<Integer> list = new ArrayList<Integer>();
list.add(intervals[0][0]);
int maxVal = intervals[0][1];
for(int i=0;i<intervals.length-1;i++) { //行
int nextLeft = intervals[i+1][0];
int nextright = intervals[i+1][1];
if(maxVal<nextLeft) { //上行右值小于下行左值
list.add(maxVal);
list.add(nextLeft);
maxVal = nextright;
}else { //上行右值大于或等于下行左值
if(maxVal<nextright) { //上行右值小于下行右值
maxVal = nextright;
}
}
}
list.add(maxVal);
//3.生成新的二维数组
int newInter[][] = new int[list.size()/2][2];
int row = 0;
for(int i=0;i<list.size();i++) {
if(i>0&&i%2==0)
row++;
newInter[row][i%2] = list.get(i);
}
return newInter;
}
此题排序是关键,对数据进行一个整理。所以有时候原数据不进行一个重新的整理归纳,会加大后面操作的难度性或后面根本无法操作!