鉴于
class Interval{
int start;
int end;
}
任务是将间隔插入到不相交的集合或间隔列表中。例如,
<4,8> into <3,7><10,13><20,21><30,31><40,45> gives <3,8><10,13><20,21><30,31><40,45>
<1,30> into <3,7><10,13><20,21><30,31><40,45> gives <1,30><40,45>
and etc.
我知道我们应该使用2个二进制搜索来获得最有效的解决方案,并且我们应该将插入的间隔开始与列表间隔进行比较&#39;结束,反之亦然。当我们无法找到我们正在寻找的内容时,我们究竟如何处理二进制搜索?
答案 0 :(得分:0)
计算节点数。返回中心,插入(如果适用)。否则,决定列表的哪一半是感兴趣的。回到它的中心,插入等。你需要处理异常&lt; 4 9&gt;进入&lt; 2&gt; &lt; 8 12&gt;。
答案 1 :(得分:0)
假设使用C ++,我会从间隔结束到间隔开始使用std::map
。
要进行搜索,请使用std::upper_bound()
查找第一个重叠
间隔然后推进迭代器以找到所有重叠的间隔。
只需要一次二进制搜索。
#include <map>
#include <stdio.h>
typedef std::map<int, int> IntervalMap;
struct Interval {
int start;
int end;
};
int main()
{
IntervalMap imap;
Interval query;
imap[7] = 3; // <3,7>
imap[13] = 10; // <10,13>
// Insert: <4,8>
query.start = 4;
query.end = 8;
// Find the first overlapping interval
auto it = imap.upper_bound(query.start);
if (it != imap.end() && it->second < query.end)
{
// There is one or more overlapping interval
// Update lower bound for the new interval
if (it->second < query.start)
query.start = it->second;
while (it != imap.end() && it->second < query.end)
{
// Update upper bound for the new interval
if (it->first > query.end)
query.end = it->first;
auto tmp = it;
++it;
imap.erase(tmp);
}
}
// Insert the new interval
imap[query.end] = query.start;
for (auto it = imap.begin(); it != imap.end(); ++it)
{
fprintf(stderr, "<%d,%d>\n", it->second, it->first);
}
return 0;
}