当前位置: 首页 > news >正文

代码训练LeetCode(49)插入区间

代码训练(49)插入区间

Author: Once Day Date: 2025年10月25日

漫漫长路,才刚刚开始…

全系列文章可参考专栏: 十年代码训练_Once-Day的博客-CSDN博客

参考文章:

  • 57. 插入区间 - 力扣(LeetCode)
  • 力扣 (LeetCode) 全球极客挚爱的技术成长平台

文章目录

      • 代码训练(49)插入区间
        • 1. 原题
        • 2. 分析
        • 3. 代码实现
        • 4. 总结

1. 原题

给你一个 无重叠的 ,按照区间起始端点排序的区间列表 intervals,其中 intervals[i] = [starti, endi] 表示第 i 个区间的开始和结束,并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval = [start, end] 表示另一个区间的开始和结束。

intervals 中插入区间 newInterval,使得 intervals 依然按照 starti 升序排列,且区间之间不重叠(如果有必要的话,可以合并区间)。

返回插入之后的 intervals

注意 你不需要原地修改 intervals。你可以创建一个新数组然后返回它。

提示:

  • 0 <= intervals.length <= 104
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 105
  • intervals 根据 starti升序 排列
  • newInterval.length == 2
  • 0 <= start <= end <= 105

示例 1:

输入:intervals = [[1,3],[6,9]], newInterval = [2,5]
输出:[[1,5],[6,9]]

示例 2:

输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
输出:[[1,2],[3,10],[12,16]]
解释:这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。
2. 分析

给定一个已经按照起始端点从小到大排列的区间列表 intervals,每个区间表示为 [starti, endi]。同时给定一个新的区间 newInterval,需要将这个新区间插入到列表中,插入后仍需保持区间列表的有序性,并且要合并所有重叠的区间。

这个问题主要考察如何有效地处理区间的插入和合并。因为原列表已经根据起始点排序,我们可以利用这一特性来优化插入过程。

解题思路:

  1. 初始化变量:创建一个新的列表 result 来保存最终的区间序列。
  2. 遍历原区间列表:对于列表 intervals 中的每一个区间:
    • 无重叠且在新区间前:如果当前区间在新区间的左侧且没有重叠,直接将其加入到 result
    • 无重叠且在新区间后:如果当前区间在新区间的右侧且没有重叠,说明新区间已经插入完毕,可以将新区间和后续的区间加入 result
    • 重叠区间:如果当前区间与新区间有重叠,合并两个区间的边界,形成一个新的合并区间。
  3. 处理未插入的新区间:如果循环结束后新区间还未插入,将其添加到 result 的末尾。

分析步骤:

  • 遍历每个区间,判断是否重叠。
  • 根据重叠情况更新新区间的起点和终点。
  • 将不重叠的区间加入结果列表。
  • 最后,确保所有区间都被处理。

性能优化关键点:

  • 空间优化:使用动态数组来避免过多的内存分配。
  • 时间优化:利用区间已排序的特性,通过一次遍历完成插入和合并,避免多次迭代。
3. 代码实现
#include <stdio.h>
#include <stdlib.h>// 结构体定义区间
typedef struct {int start;int end;
} Interval;// 动态数组结构体来存储区间序列
typedef struct {Interval* intervals;int size;int capacity;
} IntervalList;// 初始化区间列表
IntervalList* createIntervalList() {IntervalList* list = (IntervalList*)malloc(sizeof(IntervalList));list->intervals = (Interval*)malloc(10 * sizeof(Interval)); // 初始容量为10list->size = 0;list->capacity = 10;return list;
}// 动态扩展数组
void resizeIntervalList(IntervalList* list) {int newCapacity = list->capacity * 2;Interval* newIntervals = (Interval*)realloc(list->intervals, newCapacity * sizeof(Interval));if (newIntervals) {list->intervals = newIntervals;list->capacity = newCapacity;}
}// 添加区间到列表
void addInterval(IntervalList* list, Interval newInterval) {if (list->size == list->capacity) {resizeIntervalList(list);}list->intervals[list->size++] = newInterval;
}/*** 插入并合并区间* @param intervals 二维数组,表示已有的区间列表* @param intervalsSize 区间列表的大小* @param intervalsColSize 每个区间的大小(始终为2)* @param newInterval 要插入的新区间* @param newIntervalSize 新区间的大小(始终为2)* @param returnSize 返回的区间数量* @param returnColumnSizes 每个返回区间的大小数组(每个元素应为2)* @return 返回合并后的区间列表*/
int** insert(int** intervals, int intervalsSize, int* intervalsColSize, int* newInterval, int newIntervalSize, int* returnSize, int** returnColumnSizes) {// 初始化结果数组int** result = (int**)malloc((intervalsSize + 1) * sizeof(int*));*returnColumnSizes = (int*)malloc((intervalsSize + 1) * sizeof(int));int resultSize = 0;int i = 0;// 添加所有在新区间左侧且不重叠的区间while (i < intervalsSize && intervals[i][1] < newInterval[0]) {result[resultSize] = (int*)malloc(2 * sizeof(int));result[resultSize][0] = intervals[i][0];result[resultSize][1] = intervals[i][1];(*returnColumnSizes)[resultSize] = 2;resultSize++;i++;}// 合并所有与新区间重叠的区间while (i < intervalsSize && intervals[i][0] <= newInterval[1]) {newInterval[0] = newInterval[0] < intervals[i][0] ? newInterval[0] : intervals[i][0];newInterval[1] = newInterval[1] > intervals[i][1] ? newInterval[1] : intervals[i][1];i++;}result[resultSize] = (int*)malloc(2 * sizeof(int));result[resultSize][0] = newInterval[0];result[resultSize][1] = newInterval[1];(*returnColumnSizes)[resultSize] = 2;resultSize++;// 添加所有在新区间右侧且不重叠的区间while (i < intervalsSize) {result[resultSize] = (int*)malloc(2 * sizeof(int));result[resultSize][0] = intervals[i][0];result[resultSize][1] = intervals[i][1];(*returnColumnSizes)[resultSize] = 2;resultSize++;i++;}*returnSize = resultSize;return result;
}int main() {// 示例int intervalsSize = 5;int intervalsColSize[] = {2, 2, 2, 2, 2};int** intervals = (int**)malloc(intervalsSize * sizeof(int*));for (int i = 0; i < intervalsSize; i++) {intervals[i] = (int*)malloc(2 * sizeof(int));}intervals[0][0] = 1; intervals[0][1] = 2;intervals[1][0] = 3; intervals[1][1] = 5;intervals[2][0] = 6; intervals[2][1] = 7;intervals[3][0] = 8; intervals[3][1] = 10;intervals[4][0] = 12; intervals[4][1] = 16;int newInterval[] = {4, 8};int newIntervalSize = 2;int returnSize;int* returnColumnSizes;int** mergedIntervals = insert(intervals, intervalsSize, intervalsColSize, newInterval, newIntervalSize, &returnSize, &returnColumnSizes);// 打印结果for (int i = 0; i < returnSize; i++) {printf("[%d, %d] ", mergedIntervals[i][0], mergedIntervals[i][1]);}printf("\n");return 0;
}
4. 总结

这个问题是一个很好的练习,用于理解和操作区间数据。通过这个题目,我们可以学习到如何高效地合并数据范围,并且对动态数组的操作有更深的理解。对于提升编程能力,关键是掌握数据结构的选择和对算法效率的考量。

http://www.dtcms.com/a/532222.html

相关文章:

  • wordpress做游戏网站国家新闻大事
  • 【Macos】安装 macFUSE 和 SSHFS 实现在 Finder 中挂载服务器目录
  • 【高并发服务器】十、Connection连接管理模块设计与实现
  • 内网网站建设流程高佣联盟做成网站怎么做
  • Canvas 复杂交互步骤:从事件监听 to 重新绘制全流程
  • 【js】class中constructor如何接收动态值,如timeRange
  • Gorm(四)删除操作
  • XSLT `<sort>` 标签详解
  • h5游戏免费下载:读心术
  • 免费建站有哪些网站注册公司需要怎么注册
  • GDB Server使用方法(基于vscode的可视化调试)
  • Retrieval Augmented Time Series Forecasting 论文笔记
  • Vscode中选择Conda环境
  • PyCharm无法启动jupyter server问题的解决
  • 手机考勤软件哪个好?10款APP测评
  • 小游戏网站建设网络规划设计师资格证
  • 网站建设钅金手指排名十五网站做app服务端
  • Docker 拉取镜像超时问题排查与解决实录
  • 找个做游戏的视频网站好WordPress加速优化方案
  • Kafka 生产者详解(上):消息发送流程与API,分区,吞吐量与数据可靠性
  • Chrome扩展安装插件教程,Edge安装插件扩展教程,浏览器安装扩展程序方法
  • 基于Swin Transformer的糖尿病视网膜病变影像分类与诊断系统
  • 从零开始:C++ 线程池 TCP 服务器实战(续篇)
  • 免费招工人在哪个网站传奇合成版2合1雷霆版
  • AJAX家政系统同城服务多商家小程序源码
  • 《string 类模拟实现(收尾):传统与现代写法对比及底层机制探析》
  • ISCSI存储服务
  • 选择排序详解
  • 暖色网站模板wordpress 翻译 每页
  • ProcDump 学习笔记(6.9):MiniPlus 转储(-mp)——轻量却够用的现场证据