合并 C++ 中的范围
我有一个随机排序的唯一封闭范围 R0...Rn-1 列表,其中
Ri = [r1i, r2i] (r1i <= r2我)
随后一些范围重叠(部分或完全),因此需要合并。
我的问题是,用于合并此类范围的最佳算法或技术是什么。此类算法的示例或执行此类合并操作的库的链接会很棒。
I have a list of randomly ordered unique closed-end ranges R0...Rn-1 where
Ri = [r1i, r2i] (r1i <= r2i)
Subsequently some of the ranges overlap (partially or completely) and hence require merging.
My question is, what are the best-of-breed algorithms or techniques used for merging such ranges. Examples of such algorithms or links to libraries that perform such a merging operation would be great.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您需要做的是:
按字典顺序对范围键为 [r_start,r_end] 的项目进行排序
迭代排序列表并检查当前项目是否与下一个重叠。如果它确实将当前项目扩展为r[i].start,r[i+1].end,并转到下一个项目。如果不重叠,则将当前项目添加到结果列表中并移至下一个项目。
这是示例代码:
What you need to do is:
Sort items lexicographically where range key is [r_start,r_end]
Iterate the sorted list and check if current item overlaps with next. If it does extend current item to be r[i].start,r[i+1].end, and goto next item. If it doesn't overlap add current to result list and move to next item.
Here is sample code:
Boost.Icl 可能是对你有用。
该库提供了一些您可以在您的情况下使用的模板:
有一个 示例用于将间隔与库合并:
以及该算法的输出:
以及这里关于他们算法的复杂性:
加法的时间复杂度< /a>
Boost.Icl might be of use for you.
The library offers a few templates that you may use in your situation:
There is an example for merging intervals with the library :
and the output of this algorithm:
And here about complexity of their algorithms:
Time Complexity of Addition
一个简单的算法是:
A simple algorithm would be:
O(n*log(n)+2n):
r1_i
进行快速排序,r1_i
值选择最大的r2_i
值,r2_i
值,您可以跳过所有小于r2_i
的后续r1_i
O(n*log(n)+2n):
r1_i -> r2_i
,r1_i
's,r1_i
-value the largestr2_i
-value,r2_i
-value you can skip over all subsequentr1_i
's that are smaller thanr2_i
杰思罗的回答有一个错误。
应该是
jethro's answer contains an error.
It should be
我的算法不使用额外的空间,而且也是轻量级的。我使用了
2-pointer
方法。 'i' 不断增加,而 'j' 跟踪当前正在更新的元素。这是我的代码:
Interval 可以是具有数据成员“start”和“end”的公共类或结构。
快乐编码:)
My algorithm does not use extra space and is lightweight as well. I have used
2-pointer
approach. 'i' keeps increasing while 'j' keeps track of the current element being updated.Here is my code:
Interval can be a public class or structure with data members 'start' and 'end'.
Happy coding :)
我知道这距离最初接受的答案已经过去很长时间了。但在
c++11 中,我们现在可以通过以下方式
在 O(n) 比较中构造优先级队列。
请参阅 https://en.cppreference.com/w/cpp/container/优先队列/优先队列
了解更多详情。
因此我们可以在 O(n) 时间内创建一个优先级队列(最小堆)。在 O(1) 时间内获取最低间隔并在 O(log(n)) 时间内将其弹出。
所以总体时间复杂度接近 O(nlog(n) + 2n) = O(nlogn)
I know that this is a long time after the original accepted answer. But in
c++11, we can now construct a priority_queue in the following manner`
in O(n) comparisons.
Please see https://en.cppreference.com/w/cpp/container/priority_queue/priority_queue
for more details.
So we can create a priority_queue(min heap) of pairs in O(n) time. Get the lowest interval in O(1) and pop it in O(log(n)) time.
So the overall time complexity is close to O(nlog(n) + 2n) = O(nlogn)