LeetCode -- 56.合并区间

问题描述

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

示例 1:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:
输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

解题思路

首先按照每一个区间的开始值从小打到进行排序,之后只需要对二维数组遍历,判断区间是否需要合并即可。判断思路如下:

1. 如果上一个区间的结束位置大于等于当前区间的开始位置,则说明两个区间重叠,需要合并。合并后的区间开始位置不变,还是上一个区间的开始位置(因为已经按照区间开始值排序,后面区间的开始值肯定大于等于前面的区间)。而合并后的区间结束位置为上一个区间的结束位置与当前区间结束位置的最大值(因为可能会出现[1, 4], [2, 3]这种情况)。
2. 如果不满足1的条件,则说明区间不需要合并,说明此时上一个区间已经是一个无法合并且完整的区间,因此需要把上一个区间加入到结果当中。之后将当前区间作为上一个区间,继续下一轮的判断。

代码

public int[][] merge(int[][] intervals) {
      //排除特殊情况
      if (intervals.length == 0) { 
         return new int[0][2];
      }
      //按照每一个区间的start排序
      Arrays.sort(intervals, Comparator.comparingInt(interval -> interval[0]));
      
      int lastStart = intervals[0][0]; //存放上一个区间的开始位置
      int lastEnd = intervals[0][1]; //存放上一个区间的结束位置
      List<int[]> list = new ArrayList<>(); //存放结果
      for (int i = 1; i < intervals.length; i++) {
         if(lastEnd >= intervals[i][0]) { //此时需要合并区间
            lastEnd = Math.max(intervals[i][1], lastEnd); //更新变量lastEnd
         }else { //此时不需要合并区间,而要存放结果
            list.add(new int[]{lastStart, lastEnd});
            // 当前区间成为上一个区间,更新遍历,继续下一轮判断
            lastStart = intervals[i][0]; 
            lastEnd = intervals[i][1];
         }
      }
      //循环结束后,最后一个区间还没有放入结果,此时补充。
      list.add(new int[]{lastStart, lastEnd});
      return list.toArray(new int[][]{});
   }

你可能感兴趣的:(LeetCode,leetcode,算法)