【问题标题】:alternative solution to binary search just as good?二进制搜索的替代解决方案同样好?
【发布时间】:2021-02-04 23:35:26
【问题描述】:

对于二进制搜索问题,我想出了以下解决方案:

function binarySearch(arr,numba){
    
    var left = 0
    var right = arr.length - 1
    
    while (left <= right){
        let middle = Math.floor((left+right)/2)
        if (arr[middle] < numba){
            left ++;
            
        }
        else if (numba < arr[middle]){
            right -- ;
            
        }
        else if (numba === arr[middle]){
            return middle
        }
    }
    return -1
}

但建议的解决方案是:

function binarySearc(arr, elem) {
    var start = 0;
    var end = arr.length - 1;
    var middle = Math.floor((start + end) / 2);
    while(arr[middle] !== elem && start <= end) {
        if(elem < arr[middle]){
            end = middle - 1;
        } else {
            start = middle + 1;
        }
        middle = Math.floor((start + end) / 2);
    }
    if(arr[middle] === elem){
        return middle;
    }
    return -1;
}

第二种解决方案是否比我的解决方案更好,或者它们本质上是一样的?

【问题讨论】:

  • 对我来说看起来基本相同,尽管你的看起来更干净、更容易推理、重复的代码更少。有些人对“单个返回语句”很感兴趣,需要跳出循环并执行双重条件来满足他们不惜一切代价始终只有一个返回语句的渴望。
  • 在你的代码中打印leftright值,在其他代码中打印startend,区别应该很明显:你的代码是not 二分查找。

标签: javascript algorithm search binary-search


【解决方案1】:

是的,第二种解决方案更好。它是唯一实际执行二分搜索的(计算复杂度为O(log n))。请参阅下面的 sn-p 以查看需要使用建议的解决方案重新计算 middle 的次数:

function binarySearc(arr, elem) {
    var start = 0;
    var end = arr.length - 1;
    var middle = Math.floor((start + end) / 2);
    let iterCount = 0;
    while(arr[middle] !== elem && start <= end) {
        iterCount++;
        if(elem < arr[middle]){
            end = middle - 1;
        } else {
            start = middle + 1;
        }
        middle = Math.floor((start + end) / 2);
    }
    console.log('iterCount', iterCount);
    if(arr[middle] === elem){
        return middle;
    }
    return -1;
}

const arr = Array.from({ length: 100 }, (_, i) => i);
binarySearc(arr, 30);

相比之下,您的解决方案需要按O(n) 次的顺序重新分配middle - 它实际上并没有进行二分搜索。

function binarySearch(arr,numba){
    
    var left = 0
    var right = arr.length - 1
    
    let iterCount = 0;
    while (left <= right){
        iterCount++;
        let middle = Math.floor((left+right)/2)
        console.log(middle);
        if (arr[middle] < numba){
            left ++;
            
        }
        else if (numba < arr[middle]){
            right -- ;
            
        }
        else if (numba === arr[middle]){
            console.log('iterCount', iterCount);
            return middle
        }
    }
    return -1
}

const arr = Array.from({ length: 100 }, (_, i) => i);
binarySearch(arr, 30);

例如,对于长度为 100 的数组,您从 0 的 left 和 99 的 right 开始,然后在循环内的每次迭代中,您要么向左递增 1,要么向右递减 1。真二进制搜索将涉及递增或递减以将要搜索的剩余元素减少大约一半 - 例如,从 0-99 开始,然后转到 0-49,然后是 24-49,然后是 24-36,依此类推.这样您就可以比 0-99、0-98、0-97 等更快地到达目标(如果存在)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-18
    • 2018-11-12
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 2016-10-24
    • 2019-01-25
    相关资源
    最近更新 更多