学渣带你刷Leetcode0057. 合并区间

题目描述

给出一个无重叠的 ,按照区间起始端点排序的区间列表。

在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。

示例 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] 重叠。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/insert-interval
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

白话题目:
 

算法:

 

详细解释关注 B站  【C语言全代码】学渣带你刷Leetcode 不走丢 https://www.bilibili.com/video/BV1C7411y7gB

C语言完全代码

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

//方法一:遍历查找
//1,循环遍历区间列表,将和新区间无关的区间直接添加到返回列表中
//2,在循环过程中找到新区间的头位置,尾位置,并且在返回列表中预留空间
//3,将新区间或者合并后的空间插入 返回列表中预留的空间

#define     MIN(a, b)   ((a) < (b) ? (a) : (b))
#define     MAX(a, b)   ((a) > (b) ? (a) : (b))

int** insert(int** intervals, int intervalsSize, int* intervalsColSize, int* newInterval, int newIntervalSize, int* returnSize, int** returnColumnSizes){
    int     i           = 0;
    int     iRetSize    = 0;            //返回区间的个数
    int     iInsert     = 0;            //插入区间的位置
    bool    bFlag       = false;        //是否找到插入位置的标记
    bool    bHFlag      = false;        //是否找到头位置的标记
    int     iHpos       = 0;            //头位置
    int     iTpos       = 0;            //尾位置
    int**   pRet        = NULL;
    int*    pColSize    = NULL;

    //1,初始化
    pRet = (int**)malloc(sizeof(int*) * (intervalsSize + 1));
    memset(pRet, 0x00, sizeof(int*) * (intervalsSize + 1));
    pColSize = (int*)malloc(sizeof(int) * (intervalsSize + 1));
    memset(pColSize, 0x00, sizeof(int) * (intervalsSize + 1));

    //2,循环遍历区间集合,找到插入新区间的头尾
    for (i = 0; i < intervalsSize; i++)
    {
        if (intervals[i][1] < newInterval[0])
        {
            //如果新区间在当前区间的后面,则将当前区间填入返回空间
            pRet[iRetSize] = (int*)malloc(sizeof(int) * 2);
            pRet[iRetSize][0] = intervals[i][0];
            pRet[iRetSize][1] = intervals[i][1];
            pColSize[iRetSize] = 2;
            iRetSize += 1;
            continue;
        }
        else
        {
            if (!bHFlag)
            {
                //第一次区间尾大于新区间的头,则找到了新区间的头位置
                bHFlag = true;
                iHpos = i;
            }
            if (!bFlag)
            {
                //在返回空间中预留一个位置给新区间
                bFlag = true;
                iInsert = iRetSize;
                iRetSize += 1;
            }
        }

        if (intervals[i][0] > newInterval[1])
        {
            //如果新区间在当前区间的前面,则将当前区间填入返回空间时
            pRet[iRetSize] = (int*)malloc(sizeof(int) * 2);
            pRet[iRetSize][0] = intervals[i][0];
            pRet[iRetSize][1] = intervals[i][1];
            pColSize[iRetSize] = 2;
            iRetSize += 1;
        }
        else
        {
            //如果新区间的尾在当前区间的后面,则尾位置往后移
            iTpos = i;
        }
    }

    if (!bFlag)
    {
        //如果一次遍历没有找到新区间插入的位置,说明新区间在所有区间的后面
        bFlag = true;
        iInsert = iRetSize;
        iRetSize += 1;
    }

    //3,插入新区间
    pRet[iInsert] = (int*)malloc(sizeof(int) * 2);
    pColSize[iInsert] = 2;
    if (iRetSize > intervalsSize)
    {
        //如果已经插入到返回集合中的区间个数大于原来区间个数,说明新区间是个单独的区间,直接插入即可
        pRet[iInsert][0] = newInterval[0];
        pRet[iInsert][1] = newInterval[1];
    }
    else 
    {
        //说明新区间和原集合中的区间产生了重叠,需要合并区间
        pRet[iInsert][0] = MIN(intervals[iHpos][0], newInterval[0]);
        pRet[iInsert][1] = MAX(intervals[iTpos][1], newInterval[1]);
    }

    //4,返回
    *returnSize = iRetSize;
    *returnColumnSizes = pColSize;
    return pRet;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值