编程之美 - 区间重合判断

问题描述:
给定一个源区间 (x, y)和若干个无序的目标区间 (x0, y0), 
(x1, y1), (x2, y2), …… (xn, yn), 
判断源区间是否在目标区间内。

思路 1:分解源区间
把目标区间逐一的映射在源区间上,可以将源区间分解为更小的区间。最后看是否能将源区间全部分解。 例如:源区间 
{1,6},  目标区间 
{{2,3}, {3,9}, {1,2}}

step 1)  目标区间 {2, 3}  可以将源区间分解为  {1, 2}, {3, 6} step 2)  目标区间 {3, 9}  可以将源区间分解为  {1, 2},  {3, 6} 被 {3, 9}包含,全部分解掉了

step 2)  目标区间 {1, 2}  可以将源区间 {1, 2}, 全部分解掉,这样判断源区间在目标区间内。

算法复杂度: 假设有N个目标区间,那么源区间最多可能被分割N次,并且每次分割后都要遍历N次来判断新的源区集合间是否被覆蓋。复杂度为O(N*N)

思路 2:合并目标区间 先排序,再将目标区间合并为一个或多个更大的区间,最后判断这些大区间是否可以覆蓋源区间。 排序使用快速排序,排序后进行合并,例如比较y0和x1的大小可以判断两个相邻的目标区间是否有交集,如果有交集合并为一个大的区间。 最后再查找,看是否有满足  x <= xi && y <=yi 的目标区间,有的话则可以判定为覆蓋。

算法复杂度:

       排序采用快速排序的方式:O(N*Log2(N))        合并遍历一次目标区间 :  O(N)        查找遍历一次目标区间 :  O(N)

代码:

#include <iostream>
#include <vector>

using namespace std;

// seperate the source
bool fun_1(int arr_target[][2], int target_len, int* arr_src)
{
    bool find = false;
    int i = 0, j = 0, min=0, max = 0;
    int* pNew = NULL;
    vector<int*> vec_stack;
    bool *checked;

    checked = new bool[target_len];
    memset(checked, 0, target_len);

    vec_stack.push_back(arr_src);
    i = 0;
    while ((size_t)i < vec_stack.size())
    {
        min = vec_stack[i][0];
        max = vec_stack[i][1];
        for (j = 0; j < target_len; j++)
        {
            if ((!checked[j]) && 
                ((arr_target[j][0] <= min) && (arr_target[j][1] >= max)))
            {
                cout << "src " << i+1 << ":" << vec_stack.size() << " ("<< min<< ", " << max << ")" << " vs ("<< arr_target[j][0]<< ", " << arr_target[j][1] << ")  Covered"<< endl;

                checked[j] = 1;
                if ((size_t)i == vec_stack.size()-1)
                {
                    cout << "Success Covered !" << endl;
                    find = true;
                }
                break;
            }
            else if ((!checked[j]) 
                         && ((arr_target[j][0] >= max) || (arr_target[j][1] <= min)))
            {
                cout << "src " << i+1 << ":" << vec_stack.size() << " ("<< min<< ", " << max << ")" << " vs ("<< arr_target[j][0]<< ", " << arr_target[j][1] << ")  NOT Covered"<< endl;
                continue;
            }
            else if ((!checked[j]) 
                       && ((arr_target[j][0] <= min) 
                       && (arr_target[j][1] >= min)
                       && (arr_target[j][1] <= max)))
            {
                cout << "src " << i+1 << ":" << vec_stack.size() << " ("<< min<< ", " << max << ")" << " vs ("<< arr_target[j][0]<< ", " << arr_target[j][1] << ")"<< endl;
                pNew = new int[2];
                pNew[0] = arr_target[j][1];
                pNew[1] = max;
                vec_stack.push_back(pNew);
                checked[j] = 1;
                cout << "src seperate " << "(" << min<< ", " << max << ")" << " ==>  ("<< pNew[0]<< ", " << pNew[1] << ")"<< endl;
                break;
            }
            else if ((!checked[j])
                       && ((arr_target[j][0] >= min) 
                       && (arr_target[j][0] <= max) 
                       && (arr_target[j][1] >= max)))
            {
                cout << "src " << i+1 << ":" << vec_stack.size() << " ("<< min<< ", " << max << ")" << " vs ("<< arr_target[j][0]<< ", " << arr_target[j][1] << ")"<< endl;
                pNew = new int[2];
                pNew[0] = arr_target[j][0];
                pNew[1] = min;
                vec_stack.push_back(pNew);
                checked[j] = 1;
                cout << "src seperate " << "(" << min<< ", " << max << ")" 
                         << " ==>  ("<< pNew[0]<< ", " << pNew[1] << ")"<< endl;
                break;
            }
            else if ((!checked[j]) 
                        && ((arr_target[j][0] >= min) && (arr_target[j][1] <= max)))
            {
                cout << "src " << i+1 << ":" << vec_stack.size() << " ("<< min<< ", " << max << ")" << " vs ("<< arr_target[j][0]<< ", " << arr_target[j][1] << ")"<< endl;
                pNew = new int[2];
                pNew[0] = min;
                pNew[1] = arr_target[j][0];
                vec_stack.push_back(pNew);
                cout << "src seperate " << "(" << min<< ", " << max << ")" << " ==>  ("<< pNew[0]<< ", " << pNew[1] << ")  " ;

                pNew = new int[2];
                pNew[0] = arr_target[j][1];
                pNew[1] = max;
                vec_stack.push_back(pNew);
                checked[j] = 1;
                cout << "("<< pNew[0]<< ", " << pNew[1] << ")  " <<endl;
                break;
            }
        }
        i++;
    }

    for (vector<int*>::iterator it = vec_stack.begin(); it != vec_stack.end(); it++)
    {
        delete[] (*it);
        (*it) = NULL;
    }
    vec_stack.clear();
    delete[] checked;

    if (!find)
        cout << "NOT Covered !" << endl;

    return find;
}

// merge the target
void quick_sort(int arr_target[][2], int left, int right)
{
    int i = left, j = right;
    int a0 = 0, a1 = 0;

    if (left > right)
        return;

    int x0 = arr_target[left][0];
    int x1 = arr_target[left][1];

    while (i != j)
    {
        while (arr_target[j][0] >= x0 && i < j)
            j--;
        while (arr_target[i][0] <= x0 && i < j)
            i++;

        if (i < j)
        {
            a0 = arr_target[i][0]; a1= arr_target[i][1];
            arr_target[i][0] = arr_target[j][0];   arr_target[i][1] = arr_target[j][1];
            arr_target[j][0] = a0;   arr_target[j][1] = a1;
        }
    }
    arr_target[left][0] = arr_target[i][0];
    arr_target[left][1] = arr_target[i][1];

    arr_target[i][0] = x0;
    arr_target[i][1] = x1;

    quick_sort(arr_target, left, i - 1);
    quick_sort(arr_target, i + 1, right);
}

int merge(int arr_target[][2], int target_len, vector<int*> &vec_stack)
{
    int i = 0, j = 0;
    int* pNew = NULL;
    bool isSet = false;

    pNew = new int[2];
    pNew[0] = arr_target[0][0];;
    pNew[1] = arr_target[0][1];
    vec_stack.push_back(pNew);

    j = 0;
    for (i = 1; i < target_len; i++)
    {
        if ((arr_target[i][0] <= vec_stack[j][0])
            && (arr_target[i][1] >= vec_stack[j][1]))
        {
            vec_stack[j][0] = arr_target[i][0];
            vec_stack[j][1] = arr_target[i][1];
        }
        else if ((arr_target[i][0] > vec_stack[j][1]) 
                     || (arr_target[i][1] < vec_stack[j][0]))
        {
            pNew = new int[2];
            pNew[0] = arr_target[i][0];;
            pNew[1] = arr_target[i][1];
            vec_stack.push_back(pNew);
            j++;
        }
        else if ((arr_target[i][0] <= vec_stack[j][0])  
                    && (arr_target[i][1] >= vec_stack[j][0])
                    && (arr_target[i][1] <= vec_stack[j][1]))
        {
            vec_stack[j][0] = arr_target[i][0];
        }
        else if ((arr_target[i][0] >= vec_stack[j][0]) 
                    && (arr_target[i][0] <= vec_stack[j][1]) 
                    && (arr_target[i][1] >= vec_stack[j][1]))
        {
            vec_stack[j][1] = arr_target[i][1];
        }
        else if ((arr_target[i][0] >= vec_stack[j][0]) 
                     && (arr_target[i][1] <= vec_stack[j][1]))
        {
        }
    }
    return vec_stack.size();
}

bool fun_2(int arr_target[][2], int target_len, int* arr_src)
{
    int i = 0;
    bool find = false;
    vector<int*> vec_stack;

    quick_sort(arr_target, 0, target_len-1);
    merge(arr_target, target_len, vec_stack);

    for (i = 0 ; (size_t)i < vec_stack.size(); i++)
    {
        cout << "vstack: (" << vec_stack[i][0] << ", " << vec_stack[i][1] << ")" ;
        if ((arr_src[0] >= vec_stack[i][0]) && (arr_src[1] <= vec_stack[i][1]))
        {
            cout << " ==> Covered (" << arr_src[0] << ", " << arr_src[1] <<")" << endl;
            find = true;
        }
        cout << endl;
    }

    if (!find)
        cout << "NOT Covered !" << endl;

    for (vector<int*>::iterator it = vec_stack.begin(); it != vec_stack.end(); it++)
    {
        delete[] (*it);
        (*it) = NULL;
    }
    vec_stack.clear();

    return find;
}

void main()
{
    int i = 0;
    int arr_target[][2] = {{2,3}, {3,9}, {1,2}, };
    int arr_source[] = {1,6};

    //int arr_target[][2] = {{2,3}, {5,7}, {1,2}, {2, 5}, {10, 15}};
    //int arr_source[] = {1,8};

    //int arr_target[][2] = {{1,8},};
    //int arr_source[] = {1,8};

    int len = sizeof(arr_target)/(sizeof(int)*2);

    int* psrc = new int[2];
    psrc[0] = arr_source[0];
    psrc[1] = arr_source[1];

    //fun_1(arr_target, len, psrc);
    fun_2(arr_target, len, psrc);

    cin >> i;
}
点赞