[leetcode-排序]56. 合并区间

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

示例 1:

输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。

//==============================快速排序=====================================

/**
 * Definition for an interval.
 * struct Interval {
 *     int start;
 *     int end;
 * };
 */
/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */

//快速排序
int partition(struct Interval *nums, int l, int r)
{
    int low=l, high=r;
    int sentry_start = nums[low].start;
    int sentry_end = nums[low].end;
    
    while(low<high)
    {
        while(low<high && nums[high].start>=sentry_start)
        {
            high--;
        }
        nums[low].start=nums[high].start;
        nums[low].end=nums[high].end;
        
        while(low<high && nums[low].start<=sentry_start)
        {
            low++;
        }
        nums[high].start=nums[low].start;
        nums[high].end=nums[low].end;
    }
    nums[low].start=sentry_start;
    nums[low].end=sentry_end;
    
    return low;
}

void quickSort(struct Interval *nums, int l, int r){
    while(l < r)
    {
        int mid=partition(nums, l, r);
        quickSort(nums, l, mid-1);
        //quickSort(nums, mid+1, r);
        l=mid+1;
    }
}
struct Interval* merge(struct Interval* intervals, int intervalsSize, int* returnSize) {
    if(intervals==NULL || intervalsSize<1)
    {
        return NULL;
    }
    
    //先按start进行从小到大排序
    quickSort(intervals, 0, intervalsSize-1);
    
    //设置临时数组,存放合并结果
    struct Interval list[intervalsSize];
    
    int i;
    int index=0;
    int m_start=0, m_end=0;
    
    //遍历原始元素序列
    for(i=0; i<intervalsSize; ++i)
    {
        //变量存储两个初始值,用于比较
        m_start = intervals[i].start;
        m_end   = intervals[i].end;
        
        // 遍历后续元素序列,查找与其重合的元素
        // 查找规则: 
        //      1. 因为已经按start排序,只比较当前元素的end值,即当后面元素的start小于等于当前元素的end,则说明重合。
        //      2. 此处索引最大为倒数第二个,因为需要与倒数第一个元素进行比较
        while(i<intervalsSize-1 && intervals[i+1].start<=m_end)
        {
            m_end = m_end >= intervals[i+1].end ? m_end : intervals[i+1].end; //两者取大的end,start当前元素已经最小
            
            //索引前进,继续遍历
            // 1.intervals[i+1].start<=m_end 结束遍历时,后续还有元素需要遍历
            // 2. i<intervalsSize-1 结束遍历时,最后比较的是 倒数第二个元素与最后一个元素,结束时 i=intervalsSize-1 即最后一个元素的索引
            i++; 
        }
        
        //遍历的结果存放到临时结果数组
        list[index].start = m_start;
        list[index].end = m_end;
        
        //更新临时结果数组的索引
        index++;
    }
    
    //分配最后返回的结果集
    struct Interval* res = (struct Interval*)calloc(index, sizeof(struct Interval));
    
    //把临时结果集的数据转移到最后返回的结果集,其个数为index
    for(i=0; i<index; ++i)
    {
        res[i].start=list[i].start;
        res[i].end=list[i].end;
    }
    
    *returnSize=index;
    return res;
}

猜你喜欢

转载自blog.csdn.net/qq_20398345/article/details/81104852