返回

前端刷题:巧用贪心算法征服「合并区间」!

前端

  1. 题目概述

给你一个区间的集合 intervals,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间集合。

例如:

给定 intervals = [[1,3],[2,6],[8,10],[15,18]],合并后为 [[1,6],[8,10],[15,18]]。

2. 解题思路

这道题的关键在于「合并」操作,我们可以利用贪心算法来实现。贪心算法是一种通过在每一步中做出局部最优选择,最终达到全局最优解的算法。

具体步骤如下:

  1. 对 intervals 中的区间按照起始点 starti 排序。
  2. 初始化一个空列表 merged 来存储合并后的区间。
  3. 遍历 intervals 中的每个区间 [starti, endi]:
    • 如果 merged 为空或当前区间与 merged 中最后一个区间 [prev_starti, prev_endi] 不重叠,则将当前区间添加到 merged 中。
    • 否则,将当前区间与 merged 中最后一个区间合并,合并后的区间为 [min(starti, prev_starti), max(endi, prev_endi)]。

3. 代码实现

/*
 * 合并区间
 * @param {number[][]} intervals 区间集合
 * @return {number[][]} 合并后的区间集合
 */
const merge = (intervals) => {
  // 对区间按照起始点排序
  intervals.sort((a, b) => a[0] - b[0]);

  // 初始化合并后的区间列表
  const merged = [];

  // 遍历区间
  for (const interval of intervals) {
    // 如果合并后的区间列表为空或当前区间与最后一个区间不重叠,则将当前区间添加到合并后的区间列表中
    if (merged.length === 0 || merged[merged.length - 1][1] < interval[0]) {
      merged.push(interval);
    } else {
      // 否则,将当前区间与最后一个区间合并
      merged[merged.length - 1][1] = Math.max(merged[merged.length - 1][1], interval[1]);
    }
  }

  // 返回合并后的区间列表
  return merged;
};

4. 时间复杂度

本题的时间复杂度为 O(nlogn),其中 n 为 intervals 中区间的数量。排序操作需要 O(nlogn) 的时间,合并操作需要 O(n) 的时间。

5. 总结

这道题考察了我们对贪心算法的理解和应用能力。通过利用贪心算法,我们可以高效地合并重叠的区间,从而求得最终的结果。希望这篇文章能够帮助你更好地理解这道题的解法。

欢迎大家在评论区分享你们的解题思路和心得体会,也欢迎提出任何问题或建议。一起加油,在前端开发的道路上不断进步!