学习记录:js算法(六十九):合并区间

文章目录

合并区间

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

bash 复制代码
示例 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] 可被视为重叠区间。

思路一

js 复制代码
function merge(intervals) {
    // 第一步:按照区间起始位置排序
    intervals.sort((a, b) => a[0] - b[0]);

    // 初始化结果数组,至少包含第一个区间
    const merged = [intervals[0]];

    // 遍历排序后的区间列表
    for (let i = 1; i < intervals.length; i++) {
        const current = intervals[i];
        const lastMerged = merged[merged.length - 1];

        // 如果当前区间的起始位置在上一区间结束位置之后,说明无重叠,直接添加
        if (current[0] > lastMerged[1]) {
            merged.push(current);
        } else {
            // 否则,有重叠,更新上一区间的结束位置
            lastMerged[1] = Math.max(lastMerged[1], current[1]);
        }
    }

    return merged;
}

讲解

  1. 排序:首先,对输入的区间列表按照每个区间的起始位置进行升序排序。这样可以确保我们在遍历时能从左到右处理区间,更容易发现和处理重叠。
  2. 合并:遍历排序后的区间列表。对于每个区间,如果它的起始位置在结果数组的最后一个区间的结束位置之后,说明它们不重叠,直接将其加入结果数组。否则,说明有重叠,此时更新结果数组中最后一个区间的结束位置,使其覆盖当前区间的结束位置。
  3. 终止条件:遍历完整个区间列表后,结果数组即为合并后不重叠的区间列表。

思路二

js 复制代码
/**
 * @param {number[][]} intervals
 * @return {number[][]}
 */
var merge = function (intervals) {
    if (intervals.length === 0) return [];

    // 找到最大结束时间
    let maxEnd = 0;
    for (const interval of intervals) {
        maxEnd = Math.max(maxEnd, interval[1]);
    }

    // 创建一个布尔数组来标记每个时间点
    const timeline = new Array(maxEnd + 1).fill(false);

    // 标记每个区间
    for (const [start, end] of intervals) {
        for (let i = start; i <= end; i++) {
            timeline[i] = true;
        }
    }

    // 生成合并后的区间
    const merge = [];
    let start = -1;

    for (let i = 0; i < timeline.length; i++) {
        if (timeline[i]) {
            if (start === -1) {
                start = i; // 找到新的开始
            }
        } else {
            if (start !== -1) {
                merge.push([start, i - 1]); // 结束当前区间
                start = -1; // 重置开始
            }
        }
    }

    // 如果最后一个区间没有结束
    if (start !== -1) {
        merge.push([start, maxEnd]);
    }
    return merge;
};

讲解

  1. 找到最大结束时间:首先遍历所有区间,找到最大的结束时间,以便创建一个合适大小的布尔数组 timeline
  2. 标记区间:遍历每个区间,标记从 startend 的所有时间点为 true
  3. 生成合并后的区间:遍历 timeline 数组,找到连续标记为 true 的时间段,并将其作为合并后的区间添加到结果中。
  4. 处理最后一个区间:如果最后一个区间没有结束(即数组的最后一部分仍然是 true),则将其添加到结果中。
相关推荐
QuantumStack4 分钟前
【C++ 真题】P1104 生日
开发语言·c++·算法
天水幼麟26 分钟前
动手学深度学习-学习笔记【二】(基础知识)
笔记·深度学习·学习
OEC小胖胖36 分钟前
告别 undefined is not a function:TypeScript 前端开发优势与实践指南
前端·javascript·typescript·web
写个博客41 分钟前
暑假算法日记第一天
算法
绿皮的猪猪侠43 分钟前
算法笔记上机训练实战指南刷题
笔记·算法·pta·上机·浙大
沧海一笑-dj1 小时前
【51单片机】51单片机学习笔记-课程简介
笔记·学习·51单片机·江科大·江科大学习笔记·江科大单片机·江科大51单片机
行云&流水1 小时前
Vue3 Lifecycle Hooks
前端·javascript·vue.js
老虎06271 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
三水气象台1 小时前
用户中心Vue3网页开发(1.0版)
javascript·css·vue.js·typescript·前端框架·html·anti-design-vue
hie988941 小时前
MATLAB锂离子电池伪二维(P2D)模型实现
人工智能·算法·matlab