【问题标题】:Recursive bisection search to retrieve the index of a target递归二分搜索以检索目标的索引
【发布时间】:2019-03-19 23:22:53
【问题描述】:

我尝试使用二等分算法搜索查找的索引

def bi_search(nums: List[int], find: int) -> int:
    """
    Return the index of the find 
    """
    if len(nums) == 0:
        return -1
    else:
        mid = len(nums) // 2  #testEntry
        if find == nums[mid]:
            return mid 
        if find < nums[mid]:
            sub_nums = nums[:mid]
            return bi_search(sub_nums, find)  

        if find > nums[mid]:
            sub_nums = nums[mid:]
            return bi_search(sub_nums, find) #recursive case.

但它没有按预期工作

In [26]: bi_search(list(range(1000)), 777)                     
Out[26]: 4

它返回基本情况的中间。

我注意到可以使用 bisect — Array bisection algorithm — Python 3.7.3rc1 documentation 中的迭代方法检索正确的索引

是否有可能在递归解决方案中获得正确的索引?

【问题讨论】:

  • 正确的索引?你的方法更难。这是因为在最后一次迭代中,nums 将类似于 [773,774,775,776,777,778,779,780,781,782]。一个可行的递归解决方案是使用像 bi_search(nums, lower_bound, upper_bound) 这样的函数,您可以确定目标元素位于 lower_bound 和 upper_bound 的索引之间。你只需传递 nums 而不切片它。

标签: python python-3.x recursion bisection


【解决方案1】:

如果在函数中添加print() 语句并使用更小的示例,则可以看到问题:

def bi_search(nums, find):
    print((nums, find))
    ...

print(bi_search(list(range(10)), 7))

输出:

([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 7)   # Looks good.
([5, 6, 7, 8, 9], 7)                  # Also good.
2                                     # Doh!

问题在于您返回的是最后检查的列表中的索引,而不是初始列表的索引。为了使您的方法有效,您需要通过递归调用传递更多信息——这很棘手。

另一种方法是传递每次调用的完整列表,然后在进行时调整搜索的下限/上限。这还具有避免每次调用都创建新列表的优点。例如:

def bi_search(nums, find, i = None, j = None):
    # Setup.
    N = len(nums)
    if i is None:
        i = 0
        j = N - 1
    # Base case for failure.
    if j < i:
        return None
    # Success or recurse.
    mid = (i + j) // 2
    if find == nums[mid]:
        return mid 
    elif find < nums[mid]:
        return bi_search(nums, find, i, mid - 1)
    else:
        return bi_search(nums, find, mid + 1, j)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-21
    • 2013-11-28
    • 2020-06-26
    相关资源
    最近更新 更多