在Python中进行二进制搜索

时间:2015-03-16 02:40:06

标签: python arrays search binary-search

所以我有这个问题。

  

您将以非空的一维形式获得景观   数组序列。目标是找到一个坑的单元格的索引i。我们   如果seq [i]< = seq [i-1]和seq [i]< = seq [i + 1],则说seq [i]是一个坑。对于   在数组[7,6,9,7,8]中的例子中,索引1和3是凹坑。   如果它们较少,则认为第一个或最后一个元素是一个坑   超过或等于他们唯一的邻居。例如,最后一个元素   [3,2,4,4,1]是一个坑(也是索引1)。注意定义   一个坑也包括平等;例如在[3,2,2,5,5,6,6中   如图8]所示,指数1,2,3和6是凹坑。作为一个特例,我们也是   将长度为1的数组中唯一的单元格定义为凹坑。

我使用二分搜索(种类)制定了一个解决方案,以实现O(log n )作为最坏的情况时间。但是我遇到了一个没有返回或没有返回的例子。

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]))

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

您需要更改

  

&安培; (按位“和”)

  

和(逻辑“和”)

你的代码中的

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。

答案 1 :(得分:1)

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

#.... 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)