牛客-C语言解法-合并区间

 题目链接:

合并区间_牛客题霸_牛客网 (nowcoder.com)

题目简介:

描述

给出一组区间,请合并所有重叠的区间。

请保证合并后的区间按区间起点升序排列。

数据范围:区间组数 0≤n≤2×10^5,区间内 的值都满足 0≤val≤2×10^5

要求:空间复杂度 O(n),时间复杂度 O(nlogn)

进阶:空间复杂度 O(val),时间复杂度O(val)

题目解法:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

/*
 *BM89 合并区间
描述
    给出一组区间,请合并所有重叠的区间。
    请保证合并后的区间按区间起点升序排列。

数据范围:区间组数 0≤n≤2×10^5 ,区间内 的值都满足 0≤val≤2×10^5
 
要求:空间复杂度 O(n),时间复杂度 O(nlogn)
进阶:空间复杂度 O(val),时间复杂度O(val)
*/


struct Interval {
	int start;
	int end;
};
struct Interval* merge(struct Interval* intervals, int intervalsLen, int* returnSize ) {
    // write code here
    int tmpStart, tmpEnd;                   //当前开头,当前结尾
    int tmpMinStart, tmpMinEnd, tmp;        //未使用的当前最小起始区间的开头结尾
    struct Interval *retInterval = (struct Interval*)malloc(sizeof(struct Interval)*intervalsLen);     
    // int useFlag[5] = {1,1,1,1,1};  //本地测试代码
    int *useFlag = (int*)malloc(sizeof(int)*intervalsLen);    //未使用为1,已使用为0
    for(int i=0; i<intervalsLen; i++){
        *(useFlag+i) = 1;
    }
    *returnSize = 0;                        //初始化返回结构体的长度

    for(int i=0; i < intervalsLen; i++){    
        if(useFlag[i] == 0)                 //如果当前区间已使用,则跳过
            continue;
        tmpStart = intervals[i].start, tmpEnd = intervals[i].end;   //获得当前区间的起始和结尾
        tmpMinStart = -1, tmpMinEnd = -1;   //清空,初始化表示没找到最小起始区间
        useFlag[i] = 0;                     //标志当前区间已使用
        for(int j=i+1; j <= intervalsLen; j++){ //从当前区间下一个开始,循环
            if(j == intervalsLen){              //判断是否到最后一个区间
                if(tmpMinStart <= tmpEnd && tmpMinEnd >= tmpStart){   //intervals中还有未合并区间,则继续从当前区间的下一个进行循环
                    tmpMinStart = -1, tmpMinEnd = -1;
                    j = i;    //重新开始循环,相当于j=i+1
                    continue;
                }
                break;  
            }
            if(useFlag[j] == 0)             //如果当前区间已使用,则跳过
                continue;

            if(tmpStart <= intervals[j].end && tmpEnd >= intervals[j].start){    //当前区间与比较区间有重合
                useFlag[j] = 0;     //标志比较区间已使用
                tmpStart = tmpStart < intervals[j].start ? tmpStart : intervals[j].start ;//更新合并后区间的起始、结尾
                tmpEnd = tmpEnd > intervals[j].end ? tmpEnd : intervals[j].end;  
            }else{      //当前区间与比较区间没重合
                if(tmpMinStart == -1 || tmpMinStart > intervals[j].start){  //判断:1、未初始化,则赋初值 2、找到更小的起始区间
                    tmpMinStart = intervals[j].start;       //将未使用的区间且起始区间更小的比较区间记录
                    tmpMinEnd = intervals[j].end;
                }
            }
        }
        retInterval[*returnSize].start = tmpStart;      //将合并后的区间开头赋值
        retInterval[*returnSize].end = tmpEnd;          //将合并后的区间结尾赋值
        (*returnSize)++;                                //返回区间数量+1
    }

    for(int i=0; i<*returnSize; i++){                   //冒泡排序
        for(int j=i; j<*returnSize; j++){
            if(retInterval[i].start > retInterval[j].start){
                tmp = retInterval[i].start;
                retInterval[i].start = retInterval[j].start;
                retInterval[j].start = tmp;
                tmp = retInterval[i].end;
                retInterval[i].end = retInterval[j].end;
                retInterval[j].end = tmp;
            } 
        }
    }

    return retInterval;
}

/**************************end******************************************/

int main ()
{
    int retSize = 0;
    // struct Interval t1 = {10,30};
    // struct Interval t2 = {20,60};
    // struct Interval t3 = {80,100};
    // struct Interval t4 = {150,180};
    // struct Interval t1 = {10,30};
    // struct Interval t2 = {40,80};
    // struct Interval t3 = {80,100};
    // struct Interval t4 = {30,180};
    // struct Interval t1 = {1,4};
    // struct Interval t2 = {0,0};
    // struct Interval t1 = {0,2}; 
    // struct Interval t2 = {2,3};
    // struct Interval t3 = {4,4};
    // struct Interval t4 = {0,1};
    // struct Interval t5 = {5,7};
    // struct Interval t6 = {4,5};
    // struct Interval t7 = {0,0};
    struct Interval t1 = {2,3}; 
    struct Interval t2 = {4,5};
    struct Interval t3 = {6,7};
    struct Interval t4 = {8,9};
    struct Interval t5 = {1,10};
    struct Interval pt[] = {t1,t2,t3,t4,t5};
    struct Interval* ret = merge(pt, 5, &retSize);
    for(int i=0; i<retSize; i++){
        printf("\r\n [%d, %d]", (ret+i)->start, (ret+i)->end);
    }
    
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值