并集新区间

leetcode57. Insert Interval

一、题目描述

给定一组不重叠的区间,在区间中插入新的间隔(如果需要,合并)。

【举例】

例1:给定区间[1,3],[6,9],将[2,5]插入并合并为[[1,5],[6,9]]。
例2:给定[1,2],[3,5],[6,7],[8,10],[12,16],将[4,9]插入并合并为[1,2],[3,10],[12,16]。
这是因为新的区间[4,9]与[3,5],[6,7],[8,10]重叠。

二、解题思路

1)对待插入的新区间做并集
2)找到插入位置
3)更新*interval

三、解题算法

/**********************************************************************
Author:tmw
date:2018-6-20
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>

struct Interval
{
    int start;
    int end;
};

#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)

/**将newInterval区间插入intervals的index位置**/
void place( struct Interval newInterval, struct Interval* intervals, int index )
{
    intervals[index].start = newInterval.start;
    intervals[index].end = newInterval.end;
}

struct Interval* insert(struct Interval* intervals, int intervalsSize, struct Interval newInterval, int* returnSize)
{
    int i = 0;
    int mark_left = 0; /**记录新区间插入位置**/
    int mark_right = 0; /**记录新区间插入的下一个位置区间,在新区间未插入前的原始位置下标**/


    //刚开始新区间就包含0号区间
    if( newInterval.start<intervals[0].start && newInterval.end > intervals[0].end )
    {
        place(newInterval, intervals, 0);
        *returnSize = 1;
        return intervals;
    }

    while( i<intervalsSize )
    {
        /**找到新区间插入位置**/
        if( newInterval.start > intervals[i].end )
            i++;
        /**将新区间放到mark_left的位置**/
        else if( newInterval.end < intervals[i].start )
        {
            place( newInterval,intervals,mark_left );
            /**原区间左移**/
            mark_right==0?i:mark_right;
            while( mark_right <= intervalsSize-1 )
            {
                place( intervals[mark_right], intervals, mark_left++ );
                mark_right++;
            }
            *returnSize = mark_left;
            return intervals;
        }
        else/**对插入前的新区间做并集**/
        {
            /**新区间的start有更新,则记录插入位置**/
            if( newInterval.start > intervals[i].start )
            {
                mark_left = i;
                newInterval.start = min(intervals[i].start,newInterval.start);
            }
            /**新区间的end有更新,则记录mark_right**/
            if( newInterval.end < intervals[i].end )
            {
                mark_right = i+1;//i位置的区间合并,i+1位置的区间左移
                newInterval.end = max( newInterval.end, intervals[i].end );
            }
            i++;
        }
    }

    /**当遍历一遍后,新插入的区间是在末尾,则直接加在末尾**/
    //重新给intervals分配空间
    struct Interval* ptr = (struct Interval*)malloc((intervalsSize+1)*sizeof(struct Interval*));
    for(i=0; i<intervalsSize; i++)
        ptr[i] = intervals[i];
    place( newInterval, ptr, intervalsSize );
    *returnSize = intervalsSize+1;
    free(intervals);
    return ptr;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值