找到一个只有一个输入(数组)的固定点,用于函数

时间:2018-06-03 01:40:53

标签: python-3.x binary-search fixed-point

我试图使用只接受一个输入(数组)的函数在数组中找到一个固定点。问题是,我试图避免构建此函数可以调用的另一个函数。如果我能做到这一点,这种情况就会得到解决。这些数组将包含一个排序整数列表供我迭代。我试图通过使用二进制搜索来保持其运行时低。我已经尝试了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]

很好奇人们可能会发现这段代码有什么问题。

2 个答案:

答案 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]