在序列中查找元素 ai 的算法

标签 algorithm search binary-search-tree sequence

一个序列 A=[a1, a2,...,an] 是一个谷序列,如果有一个索引 i 1 < i < n 这样:

a1 > a2 > .... > ai 

ai < ai+1 < .... < an.

给定一个谷序列必须至少包含三个元素。

我真正感到困惑的是,我们如何找到一个算法来找到元素 ai,如上所述,在 O(log n) 时间? 它会类似于 O(log n) 二进制搜索吗?

如果我们确实有一个二进制搜索算法,它可以在 O(log n) 时间内找到一个数组的元素,我们可以将运行时间提高到 O(log log n) ?

最佳答案

要拥有 BIG-O(logn) 算法,我们必须在恒定时间内将问题大小减少一半。

具体来说,在这个问题中,我们可以选择一个中点,并检查它的斜率是增加的、减少的还是底部。

  • 如果斜率在增加,中点之后的部分可以忽略
  • 否则如果斜率下降,则可以忽略中点之前的部分
  • 否则中点应该是底部,因此我们找到了我们的目标。

Java 代码示例:

输入:[99, 97, 89, 1, 2, 4, 6],输出:1

public int findBottomValley(int[] valleySequence) {
    int start = 0, end = valleySequence.length - 1, mid;

    while (start + 1 < end) {
        mid = start + (end - start) / 2;

        if (checkSlope(mid, valleySequence) < 0) {
            // case decreasing
            start = mid;
        } else if (checkSlope(mid, valleySequence) > 0) {            
            // case increasing
            end = mid;
        } else {
            // find our target
            return valleySequence[mid];
        }
    }

    // left over with two points
    if (valleySequence[start] < valleySequence[end]) {
        return valleySequence[start];
    }
    return valleySequence[end];
}

辅助函数checkSlope(index, list) 将检查列表索引处的斜率,它将检查三个点,包括 index - 1、index 和 index + 1。如果斜率是递减,返回负数;如果斜率增加,返回正数;如果index-1和index+1处的数都大于index处的数,则返回0;

注意:该算法假设:

  • 列表至少包含三个项目
  • 相邻元素处的斜率不可能是平的,这是因为如果有相邻的数是相等的,那么我们就无法判断底在哪边。它可能出现在这种平坦斜坡的左侧或右侧,因此我们将不得不进行线性搜索。

由于数组的随机访问已经是常量 O(1),拥有 O(logn) 访问时间可能对算法没有帮助。

关于在序列中查找元素 ai 的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46780250/

相关文章:

algorithm - 两个循环缓冲区是否相等? (同时忽略移位)

algorithm - ACM 问题 : Coin-Flipping, 帮助我确定问题的类型

java - 实现搜索文档(PDF、XML、HTML、MS Word)搜索的最佳方法是什么?

javascript - 结合javascript函数一起工作

c - 如何找到二叉搜索树右子树中的最小值

java - 关于字符串中的括号

javascript - 如何从我的搜索表单中阻止我网站上的特定搜索词

c++ - 在递归二叉搜索树中搜索

java - 遍历节点类被另一个类继承的树

java - 使用 System.currentTimeMillis() 时出现问题;在 java