题目解读:我们的目的是将多个区间,根据覆盖的情况,相互合并成多个大的区间。每一个数组只会有两种状态,一种是保持原样,一种是和其他的数组结合成一个大数组。
解题思路 :
我们目前没有一个很好的方法,可以确定每一个一维数组是保持原样,还是和其他数组结合,所以我们就得有一种能力去搜寻这样的数组。有一个很好的方法就是,将二维数组,按照一维数组的第一个数字去进行排序。比如,[3,5] [2,4],我们应该合并成[2,5],但是在遍历到[3,5]的时候,我们如果想确定有[2,4]的存在,就需要继续遍历,这样时间复杂度就上来了,所以我们可以先用一个compare比较器进行排序。
排序之后,我们要做的就是遍历每一个一维数组,去比较前一个数组的第二个数组和后一个数组的第一个数组谁大谁小,如果后面的大,说明不需要合并,如果后面的小,说明可以进行合并操作。
如果可以进行合并操作,那就只需要再判断一下是前一个数组的第二个数字大还是后一个数组的第二个数字大就可以了,然后,一个一个数组的去遍历,去合并。
在这里,我们可以先想到的就是双端队列,因为双端队列可以帮助我们快速找到二维数组中,遍历的位置,并且操作队头和队尾。
public int[][] merge(int[][] intervals) {
LinkedList<int[]> res = new LinkedList<>();
if(intervals == null || intervals.length == 0){
return res.toArray(new int[0][]);
}
// 根据二维数组第一个数字大小按每一行整体排序
Arrays.sort(intervals,new Comparator<int []>(){
@Override
public int compare(int []o1,int[] o2){
return o1[0]-o2[0];
}
});
for(int i = 0 ; i<intervals.length ; i++){
if(res.isEmpty()||res.getLast()[1] < intervals[i][0]){
res.add(intervals[i]);
}else{
System.out.println(res.getLast()[1]);
res.getLast()[1] = Math.max(res.getLast()[1],intervals[i][1]);
}
}
return res.toArray(new int[0][0]);
}