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

文章目录

合并区间

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervalsi = 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. 标记区间:遍历每个区间,标记从 start 到 end 的所有时间点为 true。
  3. 生成合并后的区间:遍历 timeline 数组,找到连续标记为 true 的时间段,并将其作为合并后的区间添加到结果中。
  4. 处理最后一个区间:如果最后一个区间没有结束(即数组的最后一部分仍然是 true),则将其添加到结果中。
相关推荐
励志不掉头发的内向程序员1 小时前
【从零写一个CAD 03】三个 double 值得单独一个类吗:把视图变换抽成 View
开发语言·c++·qt·学习·系统架构
Doubbbbbbble云2 小时前
基于贪心算法的区间覆盖问题求解策略4
算法·贪心算法
m4Rk_8 小时前
【论文阅读】Agent 记忆机制(83):Inside Out——用可演化 PersonaTree 构建 Agent 的核心长期记忆
论文阅读·人工智能·学习·开源·github
不会就选b8 小时前
算法日常・每日刷题--<贪心>25
数据结构·算法
鬓戈9 小时前
Rust 语言与 AI 应用生态调研及学习路径
人工智能·学习·rust
传奇开心果编程9 小时前
【SwiftUI娓娓道来】第3课:让界面活起来——交互与动画指南
学习·macos·ui·ios·swiftui·swift
xian_wwq9 小时前
【学习笔记】等保合规安全基线核查实战
笔记·学习
传奇开心果编程9 小时前
【Jetpack Compose进阶学与练】第14课:系列收尾复习总结;Compose项目常见坑点汇总;学习路线与后续学习方向
android·学习·ui·kotlin·android jetpack
yangmu320310 小时前
发动机是怎么把油变成动力的:四冲程内燃机原理拆解
学习
m4Rk_10 小时前
【论文阅读】Agent 记忆机制(81):EMR——用情景记忆避免 Agent 在多步推理中反复绕圈
论文阅读·人工智能·学习·开源·github