Lan*_*lds 9 algorithm data-structures
我最近被问到关于以下问题的编码问题.我有一些解决这个问题的方法,但我不确定这些问题是否最有效.
问题:
编写程序来跟踪文本范围集.起点和终点将是字符串.
Text range example : [AbA-Ef]
Aa would fall before this range
AB would fall inside this range
etc.
Run Code Online (Sandbox Code Playgroud)
字符串比较就像'A'<'a'<'B'<'b'...'Z'<'z'
我们需要支持此范围内的以下操作
请注意,跟踪范围可以是不连续的.
我的解决方案
我提出了两种方法.
您认为这个解决方案是否足够好,或者您可以考虑采用更好的方法来实现这三个API,从而提供最佳性能?
我不清楚“删除范围”操作应该做什么。可以;
删除先前插入的范围,并重新计算剩余范围的合并?
停止跟踪已删除的范围,无论其部分内容已添加多少次。
这在算法上并没有产生巨大的差异;这只是簿记。但澄清这一点很重要。另外,范围是封闭的还是半开放的?(另一个细节不影响算法,但会影响实现)。
解决这个问题的基本方法是将跟踪集合并到不相交(不重叠)范围的排序列表中;作为向量或二叉搜索树,或者基本上任何支持 O(log n) 搜索的结构。
一种方法是将每个不相交范围的两个端点放入数据结构中。要查明目标值是否在某个范围内,请查找大于目标的最小端点的索引。如果索引是奇数,则目标在某个范围内;甚至意味着它在外面。
或者,通过起始点对所有不相交的范围进行索引;通过搜索不大于目标的最大起点来找到目标,然后将目标与相关终点进行比较。
我通常对排序向量使用第一种方法,如果 (a) 空间利用率很重要并且 (b) 插入和合并相对较少,则这种方法是合理的。对于二叉搜索树,我采用第二种方法。但它们仅在细节和常数上有所不同。
合并和删除并不困难,但是有大量令人烦恼的情况。首先查找与要插入/删除的范围的端点相对应的范围(使用标准查找操作),删除两者之间的所有范围,然后摆弄端点以纠正部分重叠的范围。虽然查找操作始终为 O(log n),但树/向量操作为 O(n)(如果插入/删除范围很大的话)。