在无限线上有一个点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)那样接缝。
有什么想法吗?
由于
答案 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)
将无限线视为无限元素数组,并要求您从任意点开始,
d
并检查每个索引是否找到值,如果找到则声明SUCCESS
和exit
,如果找不到则直到索引d
转到步骤2 2d
,仅从currentPos-d
距离开始检查值,因为在前一次迭代中已经检查了从currentPos
到currentPos-d
的索引,如果在任何索引声明SUCCESS
和exit
,如果在currentPos-2d
之前找不到,请设置d=2d
,转到step 3
。2d
,仅在currentPos+d
距离之后开始检查值,因为在上一次迭代中已经检查了从currentPos到currentPos+d
的索引,如果在任何索引处找到的值声明{ {1}}和SUCCESS
,如果在exit
之前找不到,请设置currentPos+2d
,转到d=2d
。这样你可以避免O(nx(n-1))并解析为O(n),因为你不是在每次迭代时反复检查值,在步骤2和3中你要避免检查来自currentPos的值-d和currentPos + d,当你设置d = 2d时,这就是你将algo复杂度降低到O(n)的地方和方式。