Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在预排序数组中查找给定值的最低索引_Python_Algorithm - Fatal编程技术网

Python 在预排序数组中查找给定值的最低索引

Python 在预排序数组中查找给定值的最低索引,python,algorithm,Python,Algorithm,嘿,我在一次采访中遇到了这个问题,我想知道解决这个问题的最好方法是什么。假设你得到一个已经排序的数组,你想找到某个值x的最低索引 这里是我提出的python/伪代码,我只是想知道是否有更好的方法 def findLowestIndex(arr, x): index = binarySearch(0, len(arr), x) if index != -1: while index > 0: if arr[index] == arr

嘿,我在一次采访中遇到了这个问题,我想知道解决这个问题的最好方法是什么。假设你得到一个已经排序的数组,你想找到某个值x的最低索引

这里是我提出的python/伪代码,我只是想知道是否有更好的方法

def findLowestIndex(arr, x):
     index = binarySearch(0, len(arr), x)
     if index != -1:
         while index > 0:
           if arr[index] == arr[index-1]:
              index -= 1
           else:
              break
     return index
谢谢

import bisect
l = [1,2,3,4,4,4,4,4,5,5,5,5,5,6,6,7,7,7,8,8]
bisect.bisect_left(l, 4)
编辑: 我只是错过了一件事。对分将为您提供一个插入点。因此,如果x不在列表中,您仍将有一个结果索引。因此,您需要首先检查x是否在列表中:

if x in l:
    ....

但对于面试问题,他们可能想看看你是如何提出算法而不是使用库的…

我敢打赌,g.d.d.c的评论是python最快的答案。否则,您的通用算法是正确的,除了在某些情况下您可以击败二进制搜索的O(logn)行为。具体来说,对于整数,您可以得到的最佳最坏情况行为是O(sqrt(logn)):

在最坏的情况下,您的方法需要线性时间,即数组中
x
s的计数为O(n)

通过改变二进制搜索本身,找到数组中的第一个
x
,而不是其中任何一个,可以获得O(lg n)解:

def binary_search(x, a):
    lo = 0
    hi = len(a)

    while lo < hi:
        mid = (lo + hi) // 2

        if a[mid] < x:
            lo = mid + 1
        elif a[mid] > x:
            hi = mid
        elif mid > 0 and a[mid-1] == x:
            hi = mid
        else:
            return mid

    return -1
def二进制搜索(x,a):
lo=0
hi=len(a)
当lox:
高=中
elif mid>0且a[mid-1]==x:
高=中
其他:
中途返回
返回-1

如果元素是整数或枚举的,则可以加快速度:

请注意,在二进制搜索[算法,而不是python函数]中,如果元素不存在,您可以找到比索引大的最小元素

  • 首先搜索
    x
    -并获取索引,让它成为
    i
  • 接下来,搜索
    x-1
    。如果不在列表中,则二进制搜索 如果
    x
    ,可以找到第一个索引
  • 如果它在列表中,则将找到的索引设为
    j
    • 在子列表上执行从
      j
      i
      的二进制搜索,并搜索
      list[k]
  • 对于非枚举值,也可以通过减少范围的相同想法来实现,同时
    列出[k]
    ,但我发现首先理解如何对整数进行此操作,然后将其应用于一般解更简单


    请注意,此解决方案是
    O(logn)
    ,而您建议的琐碎解决方案是
    O(n)
    ,在列表中有许多重复项,这是因为二进制搜索后的迭代步骤。

    如果
    x
    不在
    x
    中,则
    f(x)=v
    那么答案就很简单了:通过二进制搜索找到答案

    如果有一个
    x
    使得
    f(x)=v
    那么答案也很简单:用二进制搜索来找到它

    只有当存在多个
    x
    ,使得
    f(x)=v
    时,问题才有趣。如果存在恒定数量的
    x
    ,则从算法上讲,二进制搜索是最优的。只需按顺序进行二进制搜索并检查较低的索引

    但是,如果有很多这样的
    x
    ?这样的顺序搜索显然不是最优的。事实上,如果存在
    c*| X |
    X
    ,那么这将在
    O(| X |)
    中运行

    相反,可以做的是将
    lbound
    初始化为
    0
    并进行二进制搜索,直到在
    i
    找到元素,每次向右移动时,将
    lbound
    更新到刚才使用的mid。然后从
    [lbound,i-1]
    进行二进制搜索。直到
    i==lbound
    或找不到元素为止。如果出现前者,则所需索引为
    0
    。如果出现后一种情况,则所需索引为先前使用的
    i
    。最坏的情况是所需索引为
    0


    有趣的是,这仍然在
    日志(|X |)中运行。

    修改二进制搜索以第一次找到任何出现的X。

    给出了最小的索引,减少了相等分支

    def binary_search(low, high, target, array):
        while low < high:
            mid = low + (high - low) / 2
            if a[mid] < target:
                low = mid + 1
            else:
                high = mid
    
        if (array[low] == target) return low
        else return -1
    
    def二进制搜索(低、高、目标、阵列):
    低<高:
    中=低+(高-低)/2
    如果[mid]<目标:
    低=中+1
    其他:
    高=中
    如果(数组[低]==目标)返回低
    否则返回-1
    
    递归版本,如果有人感兴趣

    重写,一个来自算法4的练习

    def二进制搜索(键、a、低、高):
    如果低>高:
    返回-1;
    中=低+(高-低)/2;
    如果是[中间]<键:
    返回二进制搜索(键,a,中+1,高)
    elif a[middle]>键:
    返回二进制搜索(键、a、低、中-1)
    其他:
    如果(中间-1>=0)和(中间-1]!=键):
    返回中间
    其他:
    索引=二进制搜索(键,a,0,中间-1)
    如果(索引==-1):
    返回中间;
    其他:
    收益指数;
    a=[1,2,3,3,3,3,4,5,6,7,7,8,9]
    打印(二进制搜索(7,a,0,len(a)))
    

    递归版本不总是比非递归版本更直观吗?为什么这看起来更难。。?有谁能编写一个更好的递归版本:D吗?

    我想他们要求您不要使用
    [1,2,3]。索引(2)
    ?否则,任何方法都会显得有些过分。我有两种不同的语言,我可以用它们来编写它,所以我想要的不仅仅是python。我可以想象array.index(x)函数是高度优化的,但是该函数不能对数组的状态做出任何假设(我知道它已经被优化了)
    def binary_search(key, a, low, high):
        if low > high:
            return -1;
        middle = low + (high - low) / 2;
        if a[middle] < key:
            return binary_search(key, a, middle + 1, high)
        elif a[middle] > key:
            return binary_search(key, a, low, middle - 1)
        else:
            if (middle - 1 >= 0) and (a[middle - 1] != key):
                return middle
            else:
                index = binary_search(key, a, 0, middle - 1)
                if(index == -1):
                    return middle;
                else:
                    return index;
    
    a = [1,2,3,3,3,3,4,5,6,7,7,8,9]
    
    print(binary_search(7, a, 0, len(a)))