我有一个已排序的非重叠间隔列表(从零开始,半开),例如
{[0, 5), [10, 20), [35, 40)}
假设我在其中一个区间(例如,在这种情况下为3
)和步长值+10
(即向右移动10个位置)中有一个点。是否有算法可以在O(1)时间内计算我的最终位置? (编辑:也许我应该说,比O(n)更好的东西)
区间未涵盖的数字被视为不存在的位置,因此在上述区间内使用步骤3
定位+10
将导致最终位置19
(+1
将我的位置移至4
,然后剩下的+9
从位置10
开始到位置19
)。另一个例子是,如果我们将位置15
作为开头,步长值为-10
,那么我们的最终位置为0
。
为简单起见,我们还可以假设最终位置始终以其中一个间隔结束。但是,我们可能知道也可能不知道从哪个区间开始计算。
我当然可以在O(n)时间内迭代间隔列表(n
=间隔数)。但我觉得应该有更好的方法来攻击它。
P.S。这个问题有名字吗?这感觉它应该有一个合适的名字,但我不确定它是什么。
答案 0 :(得分:2)
您可以通过将间隔排列到二叉树中来轻松获得对数时间(非叶节点应该显示其子树的最小覆盖间隔以及实际的宽度总和)
所以,稍微改变你原来的一组间隔,
{[0, 5), [15, 20), [25,30), [35, 40)}
将表示为像
这样的树 {cover:[0,40), size:20}
/ \
{cover:[0,20), size:10} {cover:[25,40), size:10}
/ \ / \
{[0,5), 5} {[15,20), 5} {[25,30), 5} {[35,40), 5}
其中 cover 是覆盖子树的最小间隔, size 是不包括间隙的间隔宽度。
因此,为了处理您的3 + 10
案例,我们会执行以下操作:
我们向右移动(正向步骤),此间隔涵盖5-3=2
朝这个方向。 2<10
,我们尚未完成:调整剩余距离(10-2=8
)并向右移动。
当前节点是我们父节点的左子节点,因此这意味着要查看下一个正确的子节点
此时间间隔涵盖5<8
,因此我们仍未完成。调整剩余距离(8-5=3
)并再次向右移动树。
当前节点是我们父母的正确子节点,因此这意味着上升到一个级别,在这种情况下是我们祖父母的正确孩子
此时间间隔涵盖10>3
,所以我们的终点就在这里。但是,这不是一片叶子,所以我们需要从左边的孩子开始再次下降。请注意,父/子范围重叠,因此我们在此步骤中不会消耗任何剩余距离。
此时间间隔涵盖5>3
,因此我们最终找到了正确的叶间隔。我们的终点是25 + 3 = 28。
请注意,虽然遍历权看起来是线性的,但如果有的话,我们可以跳过中间子树。它不太清楚,但仍然应该是对数的。