【问题标题】:Binary Searching in PythonPython中的二进制搜索
【发布时间】:2026-02-18 02:50:01
【问题描述】:

所以我有这个问题。

给你一个非空的一维形式的风景 数组序列。目标是找到作为凹坑的单元格的索引 i。我们 如果 seq[i]

我已经制定了一个解决方案,使用二分搜索(某种)来实现 O(logn) 作为最坏情况时间。但是我遇到了一个不返回任何内容或 NONE 的示例。

def find_pit(seq):
    first = 0
    last = len(seq) - 1
    origlast = last
    mid = 0
    if len(seq) == 1 :
        return 0
    else:
        while first <= last & mid < last :
            mid = (first + last) // 2
            if seq[mid] <= seq[mid - 1] & seq[mid] <= seq[mid + 1]:
                return mid
            else:
                if seq[mid] > seq[mid - 1]:
                    last = mid
                else:
                    first = mid
    if seq[0] <= seq[1]:
        return 0
    elif seq[origlast] <= seq[origlast-1]:
        return (len(seq) - 1)

print(find_pit([0,1]))
print(find_pit([5, 4, 3, 6, 7]))

我该如何解决这个问题?

【问题讨论】:

  • 如果你代码中的elif语句不满足条件怎么办?
  • 乍一看,&amp; 运算符应该是 and 运算符;你不是在做逻辑与,你在做按位与。
  • 另外,二分查找似乎也解决不了这个问题,因为输入列表不应该被排序。
  • 但是函数在 [7, 6, 9, 7, 8] 上返回什么?在我看来,它最多只返回一个元素,否则它必须附加到结果列表或者它必须屈服,这两个都没有完成。
  • 我认为你只需要在列表中移动一个包含 3 个元素的窗口,如果 left > current 则将索引添加到结果列表/迭代器中

标签: python arrays search binary-search


【解决方案1】:

你需要改变

&(按位“与”)

and(逻辑“和”)

在您的代码中:

def find_pit(seq):
    first = 0
    last = len(seq) - 1
    origlast = last
    mid = 0
    if len(seq) == 1 :
        return 0
    else:
        #change next line to use logical and
        while first <= last and mid < last :  
            mid = (first + last) // 2
            #change next line to use logical and
            if seq[mid] <= seq[mid - 1] and seq[mid] <= seq[mid + 1]:
                return mid
            else:
                if seq[mid] > seq[mid - 1]:
                    last = mid
                else:
                    first = mid
    if seq[0] <= seq[1]:
        return 0
    elif seq[origlast] <= seq[origlast-1]:
        return (len(seq) - 1)


print(find_pit([0,1]))
print(find_pit([5, 4, 3, 6, 7]))

使用上述测试用例运行它现在将给出结果: 第一个列表为 0,第二个列表为 2。

【讨论】:

  • 起初我认为&amp; 是一个无害的错误,因为True &amp; True 仍然是True。但是&amp;运算符的优先级高于比较运算符,所以a &lt; b &amp; c &lt; d被解释为a &lt; (b &amp; c) &lt; d,导致提问者代码出现问题。
【解决方案2】:

似乎可以在给定的情况下找到第一个坑。我已经调整了调用以允许检查多个函数。

#.... original find_pit left, but not pasted in
import sys

def find_pit2(seq):

    left = sys.maxint
    maxp = len(seq)

    if maxp == 1 :
        return 0
    else:
        for pos, current in enumerate(seq):
            try:
                right = seq[pos+1]
            except IndexError:
                #rightmost, count as right neighbor as bigger
                right = sys.maxint
            #pit - smaller or equal to neighbours
            if left >= current and current <= right:
                return pos
            left = current


li_f = [find_pit, find_pit2]


for f in li_f:
    print f.__name__

    print("  ",f([0,1]))
    print("  ",f([5, 4, 3, 6, 7]))
    print("  ",f([7, 6, 9, 7, 8]))
    print("  ",f([3, 2, 2, 2, 5, 6, 6, 8]))

给予

find_pit
('  ', 0)
('  ', 2)
('  ', None)
('  ', 3)
find_pit2
('  ', 0)
('  ', 2)
('  ', 1)
('  ', 1)        

【讨论】: