javascript - 二进制搜索的替代解决方案同样好?
问题描述
对于二进制搜索问题,我提出了以下解决方案:
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;
}
第二种解决方案是否比我所拥有的更好,或者它们本质上是一样的?
解决方案
是的,第二种解决方案更好。它是唯一实际执行二分搜索的(计算复杂度为O(log n)
)。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);
相反,您的解决方案需要按时间middle
顺序重新分配O(n)
- 它实际上并没有进行二进制搜索。
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 的数组,您从left
0 和right
99 开始,然后在循环内的每次迭代中,您要么向左递增 1,要么向右递减 1。真正的二分搜索将涉及递增或递减到 cut将剩余的元素向下搜索大约一半 - 例如,从 0-99 开始,然后转到 0-49,然后是 24-49,然后是 24-36,依此类推。这样你就可以比 0-99、0-98、0-97 等更快地到达目标(如果存在)。
推荐阅读
- ruby-on-rails - FactoryBotRails 工厂中的循环依赖
- python - 使用 BeautifulSoup 和 pandas 将索引与标题值匹配时刮掉标题下方的文本
- angularjs - ng-class 直到元素没有悬停才生效
- python - 从作为 .CSV 数据文件读取的数据中删除 CRLF 中途字段,替换为“||”
- c# - 如何将 timer_ticker 设置为休眠,直到进程在后台完成
- windows - Jenkins Pipeline 不存储来自 cmd 文件的 Windows 环境变量
- deep-learning - 在每个 epoch 之后训练 MNIST 数据集时如何输出准确度和损失
- c++ - 如何在 C++ 中的最后一个数字/输出循环后删除逗号
- python - 将 dask 转换为 pandas 数据框
- c# - Powershell ProgramFiles 目录脚本