简体   繁体   English

对元素的最低索引进行二分查找

[英]Binary search for lowest index of an element

I want to implement a binary search function which returns the lowest index of the element to be searched.我想实现一个二分搜索函数,它返回要搜索的元素的最低索引。 Here is my code:这是我的代码:

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)

However, this doesn't work correctly.但是,这不能正常工作。 Can someone help me?有人能帮我吗?

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)

This fixes your issues while also giving you the lowest index这可以解决您的问题,同时还为您提供最低的指数

Time Complexity: O(log(n))时间复杂度: O(log(n))
Space Complexity: O(1)空间复杂度: O(1)

def index_equals_value_search(arr):

  left, right = 0, len(arr)-1
  lowest = -float('inf')
  while left<=right:   

    mid = (left+right)//2   
    print(mid, left, right, arr[mid])
    if arr[mid] == mid:     
      lowest = min(lowest, mid)
      right = mid-1
    elif arr[mid]<0:
       left = mid+1
    elif arr[mid]<mid:
      left = mid+1
    elif arr[mid]>mid:
      right = mid-1


  if lowest == -float('inf'): 
    return -1
  return lowest


arr = [-6,-5,-4,-1,1,3,5,7]
index_equals_value_search(arr)

You can find the index of an element which is equal to x by just adding a test for equality into the else part of your function:您只需在函数的else部分添加一个相等性测试,即可找到等于x的元素的索引:

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)

This prevents the problem of recursing past the solution, mentioned by @Fruitpunchsalami这可以防止通过@Fruitpunchsalami 提到的解决方案递归的问题

However, this won't get you the lowest index:但是,这不会让您获得最低指数:

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

Here the right answer would be 2.这里的正确答案是 2。

A further problem is the handling of elements which are not found, due to the special case of -1 .由于-1的特殊情况,另一个问题是处理未找到的元素。 We get:我们得到:

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

I would be tempted to suggest a generic solution whereby you find the index of the largest element less than x , and then check the element in the position one up from that one.我很想提出一个通用的解决方案,您可以在其中找到小于x的最大元素的索引,然后检查位置上的元素。

Finding the largest element less than x can be done in logarithmic time;可以在对数时间内找到小于x的最大元素; checking the element to the right is constant time, so you still get O(log n):检查右边的元素是常数时间,所以你仍然得到 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')

Do it all in one function:在一个函数中完成所有操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM