在一个密切排序的元素数组中搜索元素的最坏情况时间复杂度?

时间:2016-07-31 12:46:30

标签: arrays algorithm sorting search binary-search

这在我的采访中被问到,这里问题的实际含义是找到时间复杂度,或者特别是最坏情况时间复杂度,这些元素已经按排序顺序排列。

这里要注意的要点是阵列中两个相邻数字之间的差异非常小或无关紧要。

我将此问题作为一个简单的二进制搜索来处理,它要求数组按排序顺序排列,并认为最差情况时间复杂度为O(log n)。但如果问题中提到的数组元素彼此非常接近,这个答案是否会改变。

enter image description here

解决此问题的正确方法是什么。

根据这个问题,我们可以假设数组如下图所示。enter image description here

这绝对不是iam询问下面显示的内容,因为这些元素之间的区别很大,我们可以使用二进制搜索。

enter image description here

3 个答案:

答案 0 :(得分:1)

只要数组已排序,即使所有元素都相等(或“彼此非常接近”),O(log n)二进制搜索复杂度也不会改变。也许我们可以通过利用数组值分布和使用插值搜索来提高性能https://en.wikipedia.org/wiki/Interpolation_search 但如果实施不当,插值搜索可能会导致O(n)复杂性

答案 1 :(得分:1)

如果数组显示几乎线性的斜率,意味着两个连续元素之间的差异在整个数组中几乎保持不变,则可以使用线性插值来猜测可以存储值的索引:

这是JavaScript中的一个实现,但没有太多特定的语法。应该清楚发生了什么:



function search(arr, val) {
    var low, high, guess;
    low = 0;
    high = arr.length-1;
    while (low <= high && val >= arr[low] && val <= arr[high]) {
        // Use linear interpolation to make guess for index:
        guess = Math.round(low + (high - low) * (val - arr[low]) / (arr[high] - arr[low]));
        if (arr[guess] == val) return guess;
        console.log('Tried index ' + guess + '. No match yet for ' + val);
        if (arr[guess] < val) {
            low = guess + 1;
        } else {
            high = guess - 1;
        }
    }
    return -1; // not found
}


var arr = [1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16];
index = search(arr, 7);
console.log('Search result: index ' + index);
&#13;
&#13;
&#13;

当数组完全线性时,算法将在第一次猜测时找到元素,因此在 O(1)时间内。根据间隔中存在的偏差量,时间将介于 O(1) O(long n)之间。

答案 2 :(得分:0)

在正常的二分法搜索中,每次你必须将剩下的数组分成两半并检查右半部分的中位数,如果你知道元素非常接近,你可以添加一个简单的检查程序:

而不是:

  1. 检查中位数
  2. 如果中位数更大:左转
  3. 否则如果中位数较小:右转
  4. 其他返回中位数
  5. 重复
  6. 你可以修改2&amp; 3进入:通过abs向右/向左移动(中位数 - 被搜索的数字)这应该缩短您的平均案例时间复杂度,但不确定如何衡量它