學渣帶你刷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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章