題目描述
給出一個無重疊的 ,按照區間起始端點排序的區間列表。
在列表中插入一個新的區間,你需要確保列表中的區間仍然有序且不重疊(如果有必要的話,可以合併區間)。
示例 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;
}