LeetCode 56. 合并区间
我的LeetCode:https://leetcode-cn.com/u/ituring/
我的LeetCode刷题源码[GitHub]:https://github.com/izhoujie/Algorithmcii
LeetCode 56. 合并区间
题目
给出一个区间的集合,请合并所有重叠的区间。
示例 1:
输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例?2:
输入: [[1,4],[4,5]] 输出: [[1,5]] 解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-intervals
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
思路1-先按照区间起始位置排序,然后顺序合并
步骤:
- 按区间起始位置升序排序,新建与源数组长度相同的结果数组rst,并把第一个区间添加进去,此时rst长度为k=1;
- 从第二区间起,校验每个区间的左边界是否在rst最后一个区间的右边界内(<=),在则合并,否则新增进rst且k++;
- 返回rst的实际长度的部分即为合并结果;
算法复杂度: N为总区间数
- 时间复杂度: $ {\color{Magenta}{\Omicron\left(NlogN\right)}} $
- 空间复杂度: $ {\color{Magenta}{\Omicron\left(NlogN\right)}} $ -除结果数组外的排序所需空间
思路2-不排序,直接校验合并
步骤:
- 外层循环从i开始,内层循环从j=i+1开始,count记录合并次数;
- 尝试把i合并到j,若可合并则更新j摧毁i(置为null)且count++;
- 若count=0则直接返回源数组,否则拿出所有的非null区间为新数组即为结果;
算法复杂度: N为总区间数
- 时间复杂度: $ {\color{Magenta}{\Omicron\left(N^{2}\right)}} $
- 空间复杂度: $ {\color{Magenta}{\Omicron\left(1\right)}} $ -除去结果数组外
算法源码示例
package leetcode; import java.util.Arrays; import java.util.Comparator; /** * @author ZhouJie * @date 2020年2月21日 下午5:57:22 * @Description: 56. 合并区间 * */ public class LeetCode_0056 { } class Solution_0056 { /** * @author: ZhouJie * @date: 2020年2月21日 下午6:40:28 * @param: @param <T> * @param: @param intervals * @param: @return * @return: int[][] * @Description: 1- * */ public int[][] merge_1(int[][] intervals) { if (intervals == null || intervals.length == 0) { return intervals; } // 按照左边界升序排序 Arrays.sort(intervals, new Comparator<int[]>() { @Override public int compare(int[] o1, int[] o2) { return o1[0] - o2[0]; } }); int len = intervals.length; int[][] rst = new int[len][2]; rst[0] = intervals[0]; int k = 0; for (int i = 1; i < len; i++) { int x1 = intervals[i][0]; int y1 = intervals[i][1]; int y2 = rst[k][1]; // 若i的左边界小于等于rst最后一个区间的右边界,则可合并,否增新增i至rst if (x1 <= y2) { rst[k][1] = Math.max(y1, y2); } else { rst[++k] = intervals[i]; } } return Arrays.copyOf(rst, ++k); } /** * @author: ZhouJie * @date: 2020年3月4日 下午6:45:34 * @param: @param intervals * @param: @return * @return: int[][] * @Description: 2-逐步向后合并后筛选并返回; * */ public int[][] merge_2(int[][] intervals) { if (intervals == null || intervals.length == 0) { return intervals; } int len = intervals.length; int count = 0; // 每次取i和i之后的区间j对比,若可合并,则i合并到j,i自身设为null标记 for (int i = 0; i < len; i++) { for (int j = i + 1; j < len; j++) { int x1 = intervals[i][0]; int y1 = intervals[i][1]; int x2 = intervals[j][0]; int y2 = intervals[j][1]; int l = Math.min(x1, x2); int r = Math.max(y1, y2); // 判断是否可合并:ij区间的最大边界距离若小于等于ij各自区间的跨度和,则说明ij存在相接或重叠,可合并 if (r - l <= y1 - x1 + y2 - x2) { intervals[j][0] = l; intervals[j][1] = r; // 合并后,i区间null标记 intervals[i] = null; // 统计合并次数,用于判断及结果数组的长度定义 count++; break; } } } // 未合并过,直接返回于原数组 if (count == 0) { return intervals; } else { // 合并过,则新建数组,跳过null,将合并后的数组存放并返回 int[][] rst = new int[len - count][]; int k = 0; for (int[] t : intervals) { if (t != null) { rst[k++] = t; } } return rst; } } }
相关推荐
aanndd 2020-08-12
aanndd 2020-07-26
aanndd 2020-07-08
zangdaiyang 2020-07-04
yaohustiAC 2020-06-28
us0 2020-06-28
yaohustiAC 2020-06-28
zangdaiyang 2020-06-28
Clairezz 2020-06-28
嗡汤圆 2020-06-26
嗡汤圆 2020-06-21
aanndd 2020-06-16
aanndd 2020-06-16
码墨 2020-06-16
yaohustiAC 2020-06-11
zangdaiyang 2020-06-10
jiayuqicz 2020-06-09
yaohustiAC 2020-06-06
heray0 2020-06-04