问题描述:
给定一个源区间 (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;
}