在非重叠区间上行走的算法

时间:2017-04-07 11:57:49

标签: algorithm intervals

我有一个已排序的非重叠间隔列表(从零开始,半开),例如

{[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。这个问题有名字吗?这感觉它应该有一个合适的名字,但我不确定它是什么。

1 个答案:

答案 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案例,我们会执行以下操作:

  1. 常规二叉树搜索,找到包含3(对数时间)的区间
  2. 我们向右移动(正向步骤),此间隔涵盖5-3=2朝这个方向。 2<10,我们尚未完成:调整剩余距离(10-2=8)并向右移动。

    当前节点是我们父节点的左子节点,因此这意味着要查看下一个正确的子节点

  3. 此时间间隔涵盖5<8,因此我们仍未完成。调整剩余距离(8-5=3)并再次向右移动树。

    当前节点是我们父母的正确子节点,因此这意味着上升到一个级别,在这种情况下是我们祖父母的正确孩子

  4. 此时间间隔涵盖10>3,所以我们的终点就在这里。但是,这不是一片叶子,所以我们需要从左边的孩子开始再次下降。请注意,父/子范围重叠,因此我们在此步骤中不会消耗任何剩余距离。

  5. 此时间间隔涵盖5>3,因此我们最终找到了正确的叶间隔。我们的终点是25 + 3 = 28。

  6. 请注意,虽然遍历权看起来是线性的,但如果有的话,我们可以跳过中间子树。它不太清楚,但仍然应该是对数的。