当前位置:网站首页>彻底掌握二分查找
彻底掌握二分查找
2022-07-28 12:49:00 【Maic】
虽然平时业务接触算法不多,但是公司对于程序员的算法要求越来越高,基础不牢,地动山摇,优秀的程序员,算法是核心竞争力,也是解决复杂问题的一种必要手段。
前段时间加了一个刷算法题的群,也刷了leetcode的一些题目,今天一起学习掌握二分查找,熟记于心,触类旁通,达到真正掌握每种解题的方法,希望你在实际业务中有所帮助和思考。
正文开始...
二分查找
题目:给定一个有序无重复的数组arr和目标元素target,返回数组arr中target元素的下标位置
思路:在[left, right]区间中查找,指定中间位置与目标元素进行比较,如果目标元素在中间元素的左边,那么右侧区间就是[left,mid -1],如果目标元素在中间元素的右边,那么就从左侧区间开始[mid+1, right],直至找到与目标元素返回mid为止。
function binarySearch(arr, target) {
let left = 0; // 数组第一个位置
let right = arr.length -1; // 数组中最后一个位置
// [left, right] 区间查找
while(left <= right) {
// 取数组中间位置
let mid = left + Math.floor((right - left) / 2);
// 目标元素在中间位置的左边
if (target < arr[mid]) {
right = mid - 1; // [left, mid-1]
} else if (target > arr[mid]) {
// 目标元素在中间元素的右边,那么左区间[mid+1,right]
left = mid + 1;
} else {
return mid // 直到找到target,相等就直接返回mid中间下标位置
}
}
return -1; // 没有找到就返回-1
}
binarySearch([1,3,4,5,7,8], 3); // 1
用一张流程图描述一下上面的一段代码
接下来再看下具体过程
我们会发现,二分查找实际上是从中间位置开始的,如果目标值在中间位置的左边,不断的减少right区间,直至找到mid = right -1,当目标值target=3时,那么就返回mid的下标位置。
还有一种是左闭右开[left,right)
function binarySearch(arr, target) {
let left = 0; // 数组第一个位置
let right = arr.length -1; // 数组中最后一个位置
// [left,right) 区间查找
while(left < right) {
// 取数组中间位置
let mid = left + Math.floor((right - left) / 2);
// 目标元素在中间位置的左边
if (target < arr[mid]) {
right = mid; // [left, mid]
} else if (target > arr[mid]) {
// 目标元素在中间元素的右边,那么左区间[mid+1,right]
left = mid + 1;
} else {
return mid // 直到找到target,相等就直接返回mid中间下标位置
}
}
return -1; // 没有找到就返回-1
}
binarySearch([1,3,4,5,7,8], 3);
findIndex
巧用数组提供的api找到匹配的索引
function binarySearch(arr, target) {
return arr.findIndex(v => v === target)
}
binarySearch([1,3,4,5,7,8], 3); // 1
你会发现原生提供的findIndex无论数组中是否有序,还是无序都可以找到target的索引,但是findIndex也有缺陷,如果数组中有重复的值,那么只会返回第一个先找到的下标索引。
暴力for循环找索引
function binarySearch(arr = [], target) {
let index = target ? 0 : -1;
for (let i =0;i< arr.length;i++) {
if (target === arr[i]) {
index = i;
break;
} else {
index = -1;
}
}
return index;
}
binarySearch([1,3,4,5,7,8], 3); // 1
巧用map,移花接木
map这种方式的缺陷是数组中不能有重复的值,只是针对无重复的数组
function binarySearch(arr = [], target) {
const map = new Map();
arr.forEach((v, index) => {
map.set(v, index); // 将值设置成map的key
});
return map.has(target) ? map.get(target) : -1
}
binarySearch([1,3,4,5,7,8], 3); // 1
借用对象
只针对无重复数组
function binarySearch(arr = [], target) {
const result = {};
arr.forEach((v, index) => {
result[v] = index; // 将值设置成map的key
});
return Reflect.has(result, target) ? result[target]: -1
}
binarySearch([1,3,4,5,7,8], 3); // 1
总结
1、二分查找,将数组一分为二,确认中间位置,确定元素所在区域范围,如果是在左区间,则右区间则是mid - 1,左区间则固定[left, mid -1],如果元素所在区域是右区间,那么确定是右区间,右区间固定,左区间则是mid+1,[mid+1,right]
2、使用原生提供的findIndex快速寻找目标元素下标位置,最简单的一种方式
3、擅用map移花接木,利用map设置值方式,将元素值与索引存在map中,从而找到目标索引
4、利用对象存取数据,将元素值与索引存在result中,根据target从而找到目标索引
5、二分查找部分代码参考代码随想录[1]
参考资料
[1]代码随想录: https://www.programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html#_704-%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE
边栏推荐
- word打字时后面的字会消失是什么原因?如何解决?
- R language ggplot2 visualization: use the ggviolin function of ggpubr package to visualize violin diagrams, set the palette parameter, and customize the border colors of violin diagrams at different l
- Org.apache.ibatis.exceptions.toomanyresultsexception
- Half wave rectification light LED
- 图的遍历(BFS&&DFS基础)
- Deployment之滚动更新策略。
- Using fail2ban to protect web servers from DDoS Attacks
- Can second uncle cure young people's spiritual internal friction?
- leetcode-深度优先与广度优先遍历
- Today's sleep quality record 75 points
猜你喜欢

拒绝服务 DDoS 攻击

7.依赖注入

Better and more modern terminal tools than xshell!

严格模式——let和const——箭头函数——解构赋值——字符串模板symbol——Set和Map——生成器函数

30天刷题计划(四)

基于神经网络的帧内预测和变换核选择

30 day question brushing plan (II)

SAP ui5 fileuploader control realizes local file upload, and trial version of cross domain access error encountered when receiving server-side response

对“Image Denoising Using an Improved Generative Adversarial Network with Wasserstein Distance“的理解

Three men "running away" from high positions in the mobile phone factory
随机推荐
Countdown 2 days! 2022 China Computing Conference: Mobile cloud invites you to meet with computing network for innovative development
[Architecture] reading notes of three micro service books with high scores
Jar package
长封闭期私募产品再现 业内人士看法各异
剖析 kubernetes 集群内部 DNS 解析原理
.net for subtraction, intersection and union of complex type sets
R language ggplot2 visualization: use the ggviolin function of ggpubr package to visualize violin diagrams, set the palette parameter, and customize the border colors of violin diagrams at different l
Go language - Application of stack - expression evaluation
Rolling update strategy of deployment.
I miss the year of "losing" Li Ziqi
R language test sample proportion: use prop The test function performs the single sample proportion test to calculate the confidence interval of the p value of the successful sample proportion in the
LyScript 获取上一条与下一条指令
R语言ggplot2可视化:使用ggpubr包的ggviolin函数可视化小提琴图、设置palette参数自定义不同水平小提琴图的边框颜色
倒计时 2 天!2022 中国算力大会:移动云邀您共见算力网络,创新发展
R语言使用lm函数构建线性回归模型、使用subset函数指定对于数据集的子集构建回归模型(使用floor函数和length函数选择数据前部分构建回归模型)
You have to apologize if you get involved in the funny shop?
7.依赖注入
Deployment之滚动更新策略。
朋友发来几个面试题
酷炫操作预热!代码实现小星球特效