我试图使用只接受一个输入(数组)的函数在数组中找到一个固定点。问题是,我试图避免构建此函数可以调用的另一个函数。如果我能做到这一点,这种情况就会得到解决。这些数组将包含一个排序整数列表供我迭代。我试图通过使用二进制搜索来保持其运行时低。我已经尝试了100种不同的方法,但没有任何方法可行。
def fixed_point(a):
if len(a) <= 2: # tried len(a) == 0 and len(a) == 1
return -1
mid = len(a)//2 # have used (len(a)-1)//2 as well
if mid == a[mid]:
return a[mid]
if mid > a[mid]:
return find_point(a[mid+1:])
else:
return find_point(a[:mid])
return -1
如果没有找到固定点,此函数将返回-1。
这个函数也传递10000次为此构建的测试,但由于某种原因无法找到&#34; 5&#34;是数组的固定点:[ - 10,-5,-2,2,3,5,7,10,15,25,35,78,129]
很好奇人们可能会发现这段代码有什么问题。
答案 0 :(得分:1)
要重复我在评论中所说的内容,问题是您正在失去对a
的追踪。
您的方法是递归的,并且您在每次调用时都会传递缩小大小的列表。因此,你正在寻找的中间,你最终比较的中间不一样。
切换到迭代方法,您可以将内容保留在原始a
的上下文中。
def fixed_point(a):
l, u = 0, len(a)
while l <= u:
m = (l + u) // 2
if m == a[m]:
return m
elif m > a[m]:
l = m + 1
else:
u = m - 1
return -1
>>> fixed_point([-10, -5, -2, 2, 3, 5, 7, 10, 15, 25, 35, 78, 129])
5
迭代还有一个好处,即内存方面的开销较小(不需要调用堆栈),但在其他语言中,某些编译器会进行优化。
答案 1 :(得分:0)
您编写的算法的基本问题是您忘记了原始数组中的位置。递归时,返回数组一半的固定点,但是例如在[-4, -2, 0, 2, 4]
中拆分数组并找到[2, 4]
中的固定点时它不起作用,因为没有[2, 4]
中的固定点。您需要在每个递归调用中传递一个偏移量,因此您可以说if mid + offset == a[mid]
。