Leetcode435. 无重叠区间(C语言)

Leetcode435. 无重叠区间(C语言)

算法-贪心思想:算法与数据结构参考git

题目:
给定一个区间的集合,找到须要移除区间的最小数量,使剩余区间互不重叠。区间的终点老是大于它的起点。区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。例:
输入: [ [1,2], [2,3], [3,4], [1,3] ]
输出: 1

解释: 移除 [1,3] 后,剩下的区间没有重叠。github

思路:
将各区间按照起始点从小到大排序;
从头遍历各区间:
(1) 若是当前区间和上一个区间有重叠,count++;
(2) 若是当前区间和上一个区间无重叠,pre = current;
返回count;web

参考力扣大佬算法

代码:数据结构

int SelfCompare(const void *p, const void *q)
{
    int **m = (int **)p;
    int **n = (int **)q;
    if ((*m)[0] == (*n)[0]) {
        return (*m)[1] - (*n)[1];
    } else {
        return (*m)[0] - (*n)[0];   
    }
}	//按第一个排列,若第一个数相等,按后一个数排列

#define NO_OVERLAP 0
#define OVERLAP_SAME_START 1
#define OVERLAP_LOCATE_IN 2
#define OVERLAP_LOCATE_OVER 3

static int IsOverlap(int **intervals, int i, int pre){	//判断覆盖状况
    int ret = NO_OVERLAP;
    if (intervals[pre][0] == intervals[i][0]) 	//同区间起点
        ret = OVERLAP_SAME_START;
    else if (intervals[pre][1] > intervals[i][0] && intervals[pre][1] <= intervals[i][1])		//区间有交集
        ret = OVERLAP_LOCATE_IN;
    else if (intervals[pre][1] > intervals[i][1])	//区间彻底重叠
        ret = OVERLAP_LOCATE_OVER;
    
    return ret;
}

int eraseOverlapIntervals(int** intervals, int intervalsSize, int* intervalsColSize){

    if (intervals == NULL || intervalsSize < 2 || intervalsColSize == NULL) 	return 0;
    
    qsort(intervals, intervalsSize, sizeof(int *), SelfCompare);	//快排
    
    int ret = 0;
    int pre = 0;
    int i = pre + 1;	//初始化
    
    while (i < intervalsSize) {
        int flag = IsOverlap(intervals, i, pre);
        if (flag != NO_OVERLAP) 	ret++;
        else 	pre = i;	//如有重复,则计数;无重叠则继续日后遍历
        
        if (flag == OVERLAP_LOCATE_OVER) {	//区间彻底重叠时,直接去除,继续日后遍历
            intervals[pre][0] = intervals[i][0];
            intervals[pre][1] = intervals[i][1];
        }
        
        i++;
    }
    return ret;
}