在时间复杂度O(n)中求无穷直线上的点的算法

时间:2017-04-29 22:17:55

标签: algorithm time complexity-theory

在无限线上有一个点x未知位置。算法应该找到这个时间点复杂度O(n),其中n是搜索s和x的起始点之间的距离。这条线分为几步。每个步骤都有相同的长度。

我的想法是这样的:

start in s
go 1 step left
if x found { 
    terminate
 }
else {
    go 2 steps right
    if x found { 
        terminate
    }
    else {
        go 3 steps left
        ...
        ..
        .
    }
}

但这并不像O(n)那样接缝。

有什么想法吗?

由于

3 个答案:

答案 0 :(得分:2)

您已找到适合该作业的算法。

  

但这并不像O(n)那样接缝。

这个算法精确地为O(n),因为对于1和k之间的n的每个值,它只探测两次 - 一次位于x+k*s m的右侧,并且一次在位置x-k*s的左侧。这意味着该算法为O(2n),但由于常数因子总是以big-O表示法排除,因此算法为O(n)。

答案 1 :(得分:0)

我猜这有"算法"必须"步行"从s,一次只访问一个地方,总时间等于走的距离...否则你只需从两个方向上的两个方向移出两个点,直到其中一个找到目标。 (我认为这是@dasblikenlight认为你做的事情)

如果我正确地阅读了您的问题,那么,您的算法是在正确的轨道上,但要在线性时间内完成此操作,您必须在转身时以指数方式增加每个方向走的距离。

例如,您可以右转1,左2,右4,左8,右16等。每次转身时,您都会走过之前覆盖的区域,然后再次走同一距离。

让我们说你最终在某个方向走2 ^ m步时找到x。你谈到的总距离最多是p = 1 ... m的所有2 ^ p的总和。这可以达到2 ^(m + 1)-1。

此外,你知道x距离s更远2 ^(m-2)步,因为否则你会在早先的传球中找到它。

2 ^(m + 1)/ 2 ^(m-2)= 8,所以走的总距离小于8n,这当然是O(n)

答案 2 :(得分:0)

将无限线视为无限元素数组,并要求您从任意点开始,

  1. 在右侧遍历一些有限距离d并检查每个索引是否找到值,如果找到则声明SUCCESSexit,如果找不到则直到索引d转到步骤2
  2. 遍历到距离2d,仅从currentPos-d距离开始检查值,因为在前一次迭代中已经检查了从currentPoscurrentPos-d的索引,如果在任何索引声明SUCCESSexit,如果在currentPos-2d之前找不到,请设置d=2d,转到step 3
  3. 遍历距离2d,仅在currentPos+d距离之后开始检查值,因为在上一次迭代中已经检查了从currentPos到currentPos+d的索引,如果在任何索引处找到的值声明{ {1}}和SUCCESS,如果在exit之前找不到,请设置currentPos+2d,转到d=2d
  4. 这样你可以避免O(nx(n-1))并解析为O(n),因为你不是在每次迭代时反复检查值,在步骤2和3中你要避免检查来自currentPos的值-d和currentPos + d,当你设置d = 2d时,这就是你将algo复杂度降低到O(n)的地方和方式。