欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 排序题目:合并区间

排序题目:合并区间

2025/9/27 7:11:00 来源:https://blog.csdn.net/stormsunshine/article/details/125573112  浏览:    关键词:排序题目:合并区间

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:合并区间

出处:56. 合并区间

难度

5 级

题目描述

要求

给定区间数组 intervals \texttt{intervals} intervals,其中 intervals[i] = [start i , end i ] \texttt{intervals[i] = [start}_\texttt{i}\texttt{, end}_\texttt{i}\texttt{]} intervals[i] = [starti, endi],合并所有重叠的区间,并返回一个不重叠的区间数组,该数组覆盖输入中的所有区间。

示例

示例 1:

输入: intervals = [[1,3],[2,6],[8,10],[15,18]] \texttt{intervals = [[1,3],[2,6],[8,10],[15,18]]} intervals = [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]] \texttt{[[1,6],[8,10],[15,18]]} [[1,6],[8,10],[15,18]]
解释:区间 [1,3] \texttt{[1,3]} [1,3] [2,6] \texttt{[2,6]} [2,6] 重叠, 将它们合并为 [1,6] \texttt{[1,6]} [1,6]

示例 2:

输入: intervals = [[1,4],[4,5]] \texttt{intervals = [[1,4],[4,5]]} intervals = [[1,4],[4,5]]
输出: [[1,5]] \texttt{[[1,5]]} [[1,5]]
解释:区间 [1,4] \texttt{[1,4]} [1,4] [4,5] \texttt{[4,5]} [4,5] 可被视为重叠区间。

数据范围

  • 1 ≤ intervals.length ≤ 10 4 \texttt{1} \le \texttt{intervals.length} \le \texttt{10}^\texttt{4} 1intervals.length104
  • intervals[i].length = 2 \texttt{intervals[i].length} = \texttt{2} intervals[i].length=2
  • 0 ≤ start i ≤ end i ≤ 10 4 \texttt{0} \le \texttt{start}_\texttt{i} \le \texttt{end}_\texttt{i} \le \texttt{10}^\texttt{4} 0startiendi104

解法

思路和算法

为了合并数组 intervals \textit{intervals} intervals 中的所有重叠的区间,需要首先将所有的区间排序,然后判断是否有重叠的区间,并将重叠的区间合并。

对区间排序的方法是,首先将区间按照开始位置升序排序,如果存在多个区间的开始位置相同,则按照结束位置降序排序。排序之后,相同开始位置的多个区间中,第一个区间是最长的区间,对于每个开始位置只需要保留最长的区间。

由于无法事先知道合并后剩余多少个区间,因此使用列表存储合并后的区间。遍历排序后的数组 intervals \textit{intervals} intervals,首先将首个区间(即 intervals [ 0 ] \textit{intervals}[0] intervals[0])添加到列表中,然后对其余的区间依次判断是否需要和已有的区间合并,并更新列表。

由于相同开始位置的多个区间只保留最长的区间,因此对于遍历到的每个区间,需要判断该区间与数组 intervals \textit{intervals} intervals 中的上一个区间的开始位置是否相同,如果相同则跳过。当前区间不跳过时,将当前区间记为 curr \textit{curr} curr,将列表中的最后一个区间记为 prev \textit{prev} prev。由于已经对数组 intervals \textit{intervals} intervals 排序,因此 prev \textit{prev} prev 的开始位置一定小于 curr \textit{curr} curr 的开始位置。比较 curr \textit{curr} curr 的开始位置和 prev \textit{prev} prev 的结束位置,执行如下操作。

  • 如果 curr \textit{curr} curr 的开始位置小于等于 prev \textit{prev} prev 的结束位置,则 prev \textit{prev} prev curr \textit{curr} curr 重叠,需要合并,合并之后的区间的开始位置是 prev [ 0 ] \textit{prev}[0] prev[0](因为 prev [ 0 ] < curr [ 0 ] \textit{prev}[0] < \textit{curr}[0] prev[0]<curr[0]),结束位置是 max ⁡ ( prev [ 1 ] , curr [ 1 ] ) \max(\textit{prev}[1], \textit{curr}[1]) max(prev[1],curr[1])。更新 prev [ 1 ] \textit{prev}[1] prev[1] 的值,即可实现合并,不需要将 curr \textit{curr} curr 添加到列表中。

  • 如果 curr \textit{curr} curr 的开始位置大于 prev \textit{prev} prev 的结束位置,则 prev \textit{prev} prev curr \textit{curr} curr 不重叠,因此将 curr \textit{curr} curr 添加到列表中。

遍历结束之后,将列表转成数组返回。

代码

class Solution {public int[][] merge(int[][] intervals) {Arrays.sort(intervals, (a, b) -> {if (a[0] != b[0]) {return a[0] - b[0];} else {return b[1] - a[1];}});List<int[]> mergedList = new ArrayList<int[]>();mergedList.add(intervals[0]);int length = intervals.length;for (int i = 1; i < length; i++) {int[] curr = intervals[i];int[] prev = mergedList.get(mergedList.size() - 1);if (curr[0] == prev[0]) {continue;}if (curr[0] <= prev[1]) {prev[1] = Math.max(prev[1], curr[1]);} else {mergedList.add(curr);}}return mergedList.toArray(new int[mergedList.size()][]);}
}

复杂度分析

  • 时间复杂度: O ( n log ⁡ n ) O(n \log n) O(nlogn),其中 n n n 是数组 intervals \textit{intervals} intervals 的长度。排序需要 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的时间,排序后遍历数组合并区间需要 O ( n ) O(n) O(n) 的时间,时间复杂度是 O ( n log ⁡ n ) O(n \log n) O(nlogn)

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 intervals \textit{intervals} intervals 的长度。存储合并后的区间的列表需要 O ( n ) O(n) O(n) 的空间。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词