题目大意:给出一组区间,合并他们。

首先是排序,首先看start,start小的在前面。start相同的话,end小的在前面。

排序以后,要合并了。

我自己的笨方法,说实在的问题真的很多。提交了好几次才成功。

[1,2] [1, 3] [2,4]

我的判断标准是 a[i].end > a[i+1].start

很肤浅啊! 直到提示WA。给出了输入是类似这种。[1,10]  [1,3] [8,9]

后面不连续了,但是仍然被前面覆盖。

所以,应该以第i个作为一个区间,不断扩充它的end值。

直到和后面那个完全不重合了,才停止。

PS:自己写一个快速排序,也是问题多多啊!!!

首先是交换两个元素swap,都不会写了!!!想当然的就写错了!!!

然后,结构体直接赋值,居然也疑惑了,怀疑能不能直接赋值。。。

最后,判断cmp也错了。。。

/**
 * 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().
 */
bool cmp(struct Interval x, struct Interval y)
{
    return x.start < y.start || x.start == y.start && x.end < y.end;
}

void swap(struct Interval *x, struct Interval *y)
{
    struct Interval tmp = *x;
    *x = *y;
    *y = tmp;
}

int partition(struct Interval* a, int n)
{
    int last = n-1;
    int i,j;
    for(i = 0,j=0; i < n;i++)
    {
        if(cmp(a[i],a[last]))
        {
            swap(&a[i],&a[j]);
            j++;
        }
    }
    swap(&a[j],&a[last]);
    return j;
}
void quick_sort(struct Interval *a ,int n)
{
    int j;
    if(n < 2)   return;
    
    j = partition(a,n);
    quick_sort(a,j);
    quick_sort(a+j+1,n-1-j);
}

struct Interval* merge(struct Interval* intervals, int intervalsSize, int* returnSize) {
    struct Interval *a = intervals;
    int n = intervalsSize;
    
    if(n < 1)  return a;
    
    struct Interval* ans = (struct Interval* )malloc(n*sizeof(struct Interval));
    int len = 0;
    
    quick_sort(a,n);
    
    for(int i = 0; i < n; i ++)
    {
        int max_end = a[i].end;
        int min_start = a[i].start;
        
        while(i < n-1 && a[i+1].start <= max_end)  //a[i].end > a[i+1].start     //只要下一个数的起始点还在这个大区间内。
        {
            i++;
            if(a[i].end > max_end)  max_end = a[i].end;
        }
        ans[len].start = min_start;
        ans[len].end = max_end;
        len ++;
    }
    *returnSize = len;
    return ans;
}

while的代码是,只要下一个值的start比最大的end小,就更新end 的值。

最后把整个的区间放到结果里面。

 

第二种方式,参考了网上的方法。更合理,更不易出错。

先放入第一个区间,然后对于每一个区间,判断和ans中的最后一个区间是否重叠,有重叠就合并。没有就新增。

struct Interval* merge(struct Interval* intervals, int intervalsSize, int* returnSize) {
    struct Interval *a = intervals;
    int n = intervalsSize;
    
    if(n < 1)  return a;
    
    struct Interval* ans = (struct Interval* )malloc(n*sizeof(struct Interval));
    int len = 0;
    
    quick_sort(a,n);
    
    ans[0] = a[0];
    len = 1;
    
    for(int i = 1; i < n; i ++)
    {
        if(ans[len-1].end < a[i].start)     //没有交集
        {
            ans[len].start = a[i].start;
            ans[len].end = a[i].end;
            len ++;
        }
        else            //有交集,取最大的。
        {
            ans[len-1].end = ans[len-1].end > a[i].end ? ans[len-1].end : a[i].end;
        }
    }
    *returnSize = len;
    return ans;
}

 

posted on 2017-12-12 21:10  newbird2017  阅读(124)  评论(0编辑  收藏  举报