找到一个单调增加然后减少序列的数字

时间:2012-07-18 07:16:24

标签: c algorithm binary-search

在序列中找到最大值或最小值,以单调方式增加然后单调减少可以在O(log n)中完成。

但是,如果我想检查这样的序列中是否存在数字,是否也可以在O(log n)中完成?

我认为这是不可能的。考虑这个例子:1 4 5 6 7 10 8 3 2 0。

在这个例子中,如果我需要查找序列是否包含'2',我没有任何条件将搜索空间划分为原始搜索空间的一半。在最糟糕的情况下,当我们尝试搜索2时,你需要检查两半,这将是O(n)。

我想知道,如果这个搜索是在O(log n)时间内完成的吗?

3 个答案:

答案 0 :(得分:12)

如您所述,您可以在O(logn)中找到最大值(及其位置)。然后你可以在每个部分进行二进制搜索,也就是O(logn)。

在上面的示例中,您会在位置5找到最大值10。 然后在子序列[0..5](1,4,5,6,7,10)中进行二分查找。 如果找不到2,则继续在其他部分(10,8,3,2,0)进行二分查找。

要在O(logn)中找到最大值:查看中心的两个元素:7< 10.所以我们仍处于增长的阶段,必须在序列的右半部分寻找最大值:(10,8,3,2,0)。查看8和3,继续左侧部分(10,8)。

答案 1 :(得分:0)

我记得对阵列的最佳搜索是哪些元素按顺序递增然后递减是Fibonacci搜索算法。

答案 2 :(得分:0)

这是python中的草图。简而言之,我们的目标是找到一个与增加和减少区域相邻的元素(我们检查两个条件来检查相邻元素)。我们继续像标准二进制搜索那样跳跃,直到找到这个元素。希望有所帮助。

def get_max(arr):
    if len(arr) == 1:
         return arr[0]
    if len(arr) in [0,2]:
        return None
    left, right = 0, len(arr) - 1
    while left <= right:
        mid = (left+right) // 2
        #increasing region
        if arr[mid+1] >  arr[mid] and arr[mid] > arr[mid-1]:
            left = mid + 1
        #decreasing region
        elif arr[mid+1] < arr[mid] and arr[mid] < arr[mid-1]:
            right = mid - 1
        elif arr[mid+1] < arr[mid] and arr[mid-1] > arr[mid]:
            return arr[mid-1]
        else:
            return arr[mid]
    return -1