间隔范围插入,分为唯一范围

时间:2019-01-08 18:18:11

标签: javascript algorithm language-agnostic pseudocode

寻找算法思路,如何将其插入区间范围值,以使其不会与现有区间重叠。

时间间隔范围从最小到较大 [[0,1],[3,5]]进行排序。

现在插入间隔范围[0,7]到[[0,1],[3,5]]-> [[0,1],[1,3],[3,5],[5, 7]]->生成了两个新范围,其他范围保持不变。

这里是另一个示例,将范围[-3,5]插入到[[0,1],[6,7]]-> [[-3,0],[0,1],[1,5] ],[6,7]]

欢迎使用所有编程语言(尤其是JavaScript)以及伪代码实现。

1 个答案:

答案 0 :(得分:1)

  

在实际代码中,在应用某些操作后,旧的区间范围和新的区间之间会有区别,这些区间将合并在一起。我想将问题分成较小的部分,以免合并部分。

Solely:直接合并到新间隔中比较容易,而不是人为分割。这就是我在下面(C ++)提出的建议:

using DataType = /* whatever appropriate; double, int, unsigned int, ...*/;
using Interval = std::pair<DataType, DataType>;
std::vector<Interval> intervals;

void insert(Interval x)
{
    if(intervals.empty() || x.second < intervals.front().first)
    {
        intervals.insert(intervals.begin(), x); // (1)
    }
    else if(x.first > intervals.back().second)
    {
        intervals.push_back(x); // (2)
    }
    else
    {
        auto b = intervals.begin();
        while(b->second < x.first)
        {
            std::advance(b, 1);
        }
        // cannot be END iterator, otherwise would have been caught by (2)
        if(x.second < b->first)
        {
            // this is a new interval in between std::prev(b) and (b)
            intervals.insert(b, x);
        }
        else
        {
            // b is overlapping with x!
            if(b->first > x.first)
            {
                b->first = x.first;
            }

            auto e = std::next(b);
            while(e != intervals.end() && e->first <= x.second)
            {
                std::advance(e, 1);
            }
            // e is the first interval NOT overlapping with x!
            auto l = std::prev(e);
            b->second = std::max(x.second, l->second);
            // drop all subsequent intervals now contained in b (possibly none)
            intervals.erase(std::next(b), e);
        }
    }
}

仅算法,节省了打包到类中的设计工作,具有接受开始/结束标记(而不是间隔)的便捷功能,...

如果您要使用的数据类型不提供反向访问器(C ++:例如std::forward_list):没问题,只需删除第二个if(包含(2))即可;然后,b 可以成为结束迭代器,因此您必须进行测试,如果测试成功,则可以在末尾插入。那时您很可能没有“插入”,因此您也需要分别跟踪b和e的前身...