二进制搜索元素的最低索引

时间:2017-01-10 16:45:11

标签: python binary-search

我想实现一个二进制搜索函数,它返回要搜索的元素的最低索引。这是我的代码:

def binarySearch(arr,x):
    n=len(arr)
    if n==1:
        if arr[0]==x:
            return 0
        else:
            return -1 # not in list
    else:
        m=int(n/2)
        if x <= arr[m]:
            return binarySearch(arr[:m],x)
        else:
            return m+binarySearch(arr[m+1:],x)

但是,这不能正常工作。有人能帮助我吗?

2 个答案:

答案 0 :(得分:1)

def binarySearch(arr,x):

    if len(arr) == 0:
        return 0

    else:
        m=int(len(arr)/2)

        if arr[m] == x:
            c = 1

            while arr[m-c] == x:
                c += 1
            return m-c+1

        else:
            if x < arr[m]:
                return binarySearch(arr[:m],x)
            else:
                return binarySearch(arr[m+1:],x)

这可以解决您的问题,同时也为您提供最低的索引

答案 1 :(得分:0)

您可以通过在函数的x部分添加相等性测试来找到等于else元素的索引:

def binarySearch(arr,x):
    n=len(arr)
    if n==1:
        if arr[0]==x:
            return 0
        else:
            return -1 # not in list
    else:
        m = int(n/2)
        if x < arr[m]:
            return binarySearch(arr[:m],x)
        elif x == arr[m]:
            return m
        else:
            return m + binarySearch(arr[m+1:],x)

这可以防止在@Fruitpunchsalami

中提到的解决方案的递归问题

然而,这不会得到最低指数:

>>> binarySearch([1,2,3,3,4,4], 3)
3

这里正确答案是2。

由于-1的特殊情况,另一个问题是处理未找到的元素。我们得到:

>>> binarySearch([1,2,3,3,6,6], 4)
2

我很想建议一个通用的解决方案,你找到最小元素的索引小于x,然后检查那个位置中的元素。

找到小于x的最大元素可以在对数时间内完成;检查右边的元素是恒定时间,所以你仍然得到O(log n):

def binarySearch(arr,x):
    '''Returns the lowest index of the element equal to `x` or NaN if not found.'''
    def innerBinarySearch(arr, x):
        '''Find index of largest element strictly less than `x`.'''
        if len(arr) == 0:
            return -1
        m = len(arr) // 2
        if x <= arr[m]:
            return innerBinarySearch(arr[:m], x)
        else:
            return m + 1 + innerBinarySearch(arr[m + 1:], x)

    idx = innerBinarySearch(arr,x) + 1
    if 0 <= idx < len(arr) and arr[idx] == x:
        return idx
    return float('nan')

在一个功能中完成所有操作:

def binarySearch(arr,x):
    '''Returns the lowest index of the element equal to `x` or NaN if not found.'''
    if len(arr) == 0:
        return float('nan')
    m = len(arr) // 2
    if arr[m] < x:
        return m + 1 + binarySearch(arr[m + 1:], x)
    elif x < arr[m] or (0 < m and arr[m-1] == x):
        return binarySearch(arr[:m], x)
    else:
        return m