繁体   English   中英

使用Binary Search将Interval插入不相交的间隔中

[英]Insert Interval into a disjoint set of intervals with Binary Search

给定

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个二进制搜索来找到最有效的解决方案,并且我们应该比较插入间隔的开始与列表间隔的结束,反之亦然。 当我们找不到确切要寻找的东西时,我们如何处理二进制搜索?

计算节点数。 返回中心,如果适用,插入。 否则,确定列表中的哪一半是您感兴趣的。 返回其中心,插入等。您需要将异常<4 9>放入<2 5> <8 12>中。

假设使用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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM