問題描述:
給定乙個源區間 (x, y)和若干個無序的目標區間 (x0, y0),
(x1, y1), (x2, y2), ...... (xn, yn),
判斷源區間是否在目標區間內。
思路 1:分解源區間
把目標區間逐一的對映在源區間上,可以將源區間分解為更小的區間。最後看是否能將源區間全部分解。
例如:源區間
, 目標區間
, , }
step 1) 目標區間 可以將源區間分解為 ,
step 2) 目標區間 可以將源區間分解為 , 被 包含,全部分解掉了
step 2) 目標區間 可以將源區間 , 全部分解掉,這樣判斷源區間在目標區間內。
演算法複雜度:
假設有n個目標區間,那麼源區間最多可能被分割n次,並且每次分割後都要遍歷n次來判斷新的源區集合間是否被覆蓋。複雜度為o(n*n)
思路 2:合併目標區間
先排序,再將目標區間合併為乙個或多個更大的區間,最後判斷這些大區間是否可以覆蓋源區間。
排序使用快速排序,排序後進行合併,例如比較y0和x1的大小可以判斷兩個相鄰的目標區間是否有交集,如果有交集合併為乙個大的區間。
最後再查詢,看是否有滿足 x <= xi && y <=yi 的目標區間,有的話則可以判定為覆蓋。
演算法複雜度:
排序採用快速排序的方式:o(n*log2(n))
合併遍歷一次目標區間 : o(n)
查詢遍歷一次目標區間 : o(n)
**:
#include #include using namespace std;
// seperate the source
bool fun_1(int arr_target[2], int target_len, int* arr_src)
break;
}else if ((!checked[j])
&& ((arr_target[j][0] >= max) || (arr_target[j][1] <= min)))
else if ((!checked[j])
&& ((arr_target[j][0] <= min)
&& (arr_target[j][1] >= min)
&& (arr_target[j][1] <= max)))
else if ((!checked[j])
&& ((arr_target[j][0] >= min)
&& (arr_target[j][0] <= max)
&& (arr_target[j][1] >= max)))
else if ((!checked[j])
&& ((arr_target[j][0] >= min) && (arr_target[j][1] <= max)))
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)
}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&vec_stack)
else if ((arr_target[i][0] > vec_stack[j][1])
|| (arr_target[i][1] < vec_stack[j][0]))
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]))
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]))
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)
cout << endl;
}if (!find)
cout << "not covered !" << endl;
for (vector::iterator it = vec_stack.begin(); it != vec_stack.end(); it++)
vec_stack.clear();
return find;
}void main()
, , , };
int arr_source = ;
//int arr_target[2] = , , , , };
//int arr_source = ;
//int arr_target[2] = ,};
//int arr_source = ;
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;
}
程式設計之美2 19 區間重合判斷
題目 給定乙個源區間 x,y y x 和n個無序的目標區間 x1,y1 x2,y2 x3,y3 xn,yn 判斷源區間 x,y 是不是在目標區間內?例如,給定源區間 1,6 和一組無序的目標區間 2,3 1,1 3,9 即可認為區間 1,6 在區間 2,3 1,1 3,9 內,因為目標區間實際上是 ...
程式設計之美 2 19 區間重合判斷
題目大意 給定源區間 x,y x y 和 n個無序的目標區間 xi,yi 1 i n 判斷源區間是否在目標區間內。分析 書中介紹了兩種解法。第一種 將目標區間投影到源區間,看最終未被覆蓋的區間是否變為。這種方法的複雜度無疑是很高的。o n 2 另外,對於k組源區間查詢,其複雜度是單次的k倍。第二種 ...
程式設計之美 2 19 區間重合判斷
給定乙個源區間 x,y y x 和n個無序的目標區間 x1,y1 x2,y2 xn,yn 判斷源區間 x,y 是不是在目標區間內 eg,給定乙個源區間 1,6 和一組無序的目標區間 2,3 1,2 3,9 即可認為 1,6 在區間 2,3 1,2 3,9 內 因為目標區間合併之後,實質為 1,9 i...