【发布时间】:2022-08-19 15:15:08
【问题描述】:
给定一组排序区间(first >= second),按区间的第一个元素排序:
{1, 3}, {1, 2}, {2, 4}, {2, 2}, {2, 3}, {3, 5}, {3, 3}, {3, 7}
是否有一种有效的算法来确定与给定相交的第一个区间 输入间隔?例如:
Query ({0, 0}) = returns end()
Query ({2, 4}) = returns iterator to element 0
Query ({3, 8}) = returns iterator to element 0
Query ({4, 9}) = returns iterator to element 2
Query ({7, 8}) = returns iterator to element 7
Query ({8, 9}) = returns end()
高效我的意思是比 O(N) 更好。我有一种模糊的感觉下限或者上限这个问题的解决方案,但我没有精神力来解决它是什么。
这是我不满意的 O(N) 解决方案。
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
int main()
{
using Interval = std::pair<int, int>;
using Sequence = std::vector<Interval>;
using Iterator = Sequence::const_iterator;
auto Query = [](Sequence const & sequence, Interval const & interval) -> Iterator
{
return std::find_if(sequence.begin(), sequence.end(), [interval](Interval const & other) {
return interval.first <= other.second && interval.second >= other.first;
});
};
auto Print = [](Sequence const & sequence, Iterator const & iterator) -> void
{
if (iterator == sequence.cend())
{
std::cout << \"end()\\n\";
}
else
{
std::cout << std::to_string(std::distance(sequence.cbegin(), iterator)) << \"\\n\";
}
};
Sequence sequence = {
{1, 3}, { 1, 2 }, { 2, 4 }, { 2, 2 }, { 2, 3 }, { 3, 5 }, { 3, 3 }, { 3, 7 }
};
auto result = Iterator();
result = Query(sequence, { 0, 0 });
Print(sequence, result);
result = Query(sequence, { 2, 4 });
Print(sequence, result);
result = Query(sequence, { 3, 8 });
Print(sequence, result);
result = Query(sequence, { 4, 9 });
Print(sequence, result);
result = Query(sequence, { 7, 8 });
Print(sequence, result);
result = Query(sequence, { 8, 9 });
Print(sequence, result);
}
输出:
end()
0
0
2
7
end()
-
您是否一定要以这种方式存储数据,或者这是您迄今为止想出但愿意改变的东西?我问 b/c 有一个更好的数据结构,我认为......
-
您不能跳过任何左边界低于请求区间右边界的区间,因为右边界(没有排序/约束)总是可以假设一个可能使检查的区间相交的值,所以你不能使用二分搜索立即跳转到“有趣的区域”。您可以使用此数据布局的唯一改进是在检查的间隔左边界大于请求的间隔右边界时提前退出。
-
@NathanOliver 我不认为你可以进行二进制搜索。向量排序为剩下区间的点;正确的点可以是任意的。
-
@NathanOliver二进制搜索可以确定的唯一一件事是您可以在向量中的哪个位置结束搜索,因为每个后续值都将从一个太大的值开始,以至于无法在那里找到所需的值。我认为您仍然需要在该范围内执行线性搜索,如果这样做,您无论如何都会找到这个早期的结束值,您不需要先搜索它。
-
我发现了一个叫做“间隔树”的东西......我想知道这是否是 Lorro 的意思......dgp.toronto.edu/public_user/JamesStewart/378notes/22intervals