面试官,我会写二分查找法!对,没有 bug 的那种!
前言科普
第一篇二分搜索论文是 1946 年发表,然而第一个没有 bug 的二分查找法却是在 1962 年才出现,中间用了 16 年的时间。
2019 年的你,在面试的过程中能手写出没有 bug 的二分查找法么?
定义
在计算机科学中,二分查找(英语:binary search),也称折半搜索(英语:half-interval search)、对数搜索(英语:logarithmic search),是一种在有序数组中查找某一特定元素的搜索算法。
搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;
如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。
如果在某一步骤数组为空,则代表找不到。
这种搜索算法每一次比较都使搜索范围缩小一半。
二分查找法代码
按照上面的定义,我们来尝试写一下二分查找法的代码。
public static int binary(int[] arr, int data) {
int min = 0;
int max = arr.length - 1;
int mid;
while (min <= max) {
mid = (min + max) / 2;
if (arr[mid] > data) {
max = mid - 1;
} else if (arr[mid] < data) {
min = mid + 1;
} else {
return mid;
}
}
return -1;
}
现在问你,上面的代码有没有问题?哪段代码会出现 bug ?
请思考一分钟后再往下查看。
对于上面这段代码而言,问题出在第 6 行代码处:
mid = (min + max) / 2;
这句代码在 min 和 max 很大的时候,会出现溢出的情况,从而导致数组访问出错。
别看现在轻描淡写的指出了这个错误,但这个错误在当时可是存在了好些年。
那怎么改进呢?一般的做法是这样的:将加法变成减法。
public static int binary(int[] arr, int data) {
int min = 0;
int max = arr.length - 1;
int mid;
while (min <= max) {
// 防止溢出
mid = min + (max - min) / 2;
if (arr[mid] > data) {
max = mid - 1;
} else if (arr[mid] < data) {
min = mid + 1;
} else {
return mid;
}
}
return -1;
}
还有一种更高逼格的写法,也是官方的二分搜索法的实现写法:使用 位运算。
public static int binary(int[] arr, int data) {
int min = 0;
int max = arr.length - 1;
int mid;
while (min <= max) {
// 无符号位运算符的优先级较低,先括起来
mid = min + ((max - min) >>> 1);
if (arr[mid] > data) {
max = mid - 1;
} else if (arr[mid] < data) {
min = mid + 1;
} else {
return mid;
}
}
return -1;
}
希望通过今天的文章能帮助读者们在面试中手写对代码,毕竟,对于很多小公司来说,二分查找法会出现在他们的笔试题中的。

面试官,我会写二分查找法!对,没有 bug 的那种!的更多相关文章
- 二分查找法 java
前几天去面试,让我写二分查找法,真是哔了狗! 提了离职申请,没事写写吧! 首先二分查找是在一堆有序的序列中找到指定的结果. public class Erfen { public static int ...
- 用c语言编写二分查找法
二分法的适用范围为有序数列,这方面很有局限性. #include<stdio.h> //二分查找法 void binary_search(int a[],int start,int mid ...
- python 全栈开发,Day15(递归函数,二分查找法)
一.递归函数 江湖上流传这这样一句话叫做:人理解循环,神理解递归.所以你可别小看了递归函数,很多人被拦在大神的门槛外这么多年,就是因为没能领悟递归的真谛. 递归函数:在一个函数里执行再调用这个函数本身 ...
- 二分查找法(java版)
二分查找法也称为折半查找法,在有序的序列中使用二分法可以提高程序的执行效率. 典型的二分查找法代码 public int binarySearch1(int[] arr,int target){ in ...
- 二分查找法&大O表示法
二分查找法的输入是一个有序的元素列表,如果要查找的元素包含在列表中,二分查找返回其位置,否则返回null Python代码(来源于<算法图解>一书): def binary_search( ...
- jvascript 顺序查找和二分查找法
第一种:顺序查找法 中心思想:和数组中的值逐个比对! /* * 参数说明: * array:传入数组 * findVal:传入需要查找的数 */ function Orderseach(array,f ...
- java for循环和数组--冒泡排序、二分查找法
//100以内与7相关的数 for(int a=1;a<=100;a++){ if(a%7==0||a%10==7||a/10==7){ System.out.print(a+ ...
- 学习练习 java 二分查找法
package com.hanqi; import java.util.*; public class Test5 { public static void main(String[] args) { ...
- Java-数据结构与算法-二分查找法
1.二分查找法思路:不断缩小范围,直到low <= high 2.代码: package Test; import java.util.Arrays; public class BinarySe ...
随机推荐
- win10系统怎么设置软件开机启动
win10开机自动启动软件设置教程: 1:在windows10桌面,右键点击桌面左下角的开始按钮,在弹出的菜单中选择运行菜单项. 2:这时就会打开windows10的运行窗口,在窗口中输入命令shel ...
- springaop\ cglib\ AspectJ
元编程 vs 动态代理 vs isa代理 springaop的底层实现有两种,一种是jdk的动态代理,另一种是cglib,springaop没有用到aspectj,只是借鉴了它并添加了aspectj风 ...
- execjs使用时异常
一.异常信息(...gbk.....) UnicodeDecodeError: 'gbk' codec can't decode byte 0xa1 in position 26: illegal m ...
- FCC---Create a Gradual CSS Linear Gradient
Applied Visual Design: Create a Gradual CSS Linear Gradient background: linear-gradient(gradient_dir ...
- echarts关系图圆心颜色渐变
let option = { backgroundColor: '#1a4377', animationDurationUpdate: 1500, // 动画更新变化时间 animationEasin ...
- echarts玩转图表之矩形树图
前言 这是第一次用makedown编辑器写文章,感觉像一件利器,排版美观而且效率飙升.进入正题 Echart官网文档地址 针对于矩形树图api配置项链接 1. 完全从数据定义图形 $.get( &qu ...
- ORACLE关于日志文件基本操作
1.查询系统使用的是哪一组日志文件:SELECT * FROM V$LOG; 2.查询正在使用的组所对应的日志文件:SELECT * FROM V$LOGFILE; 3.强制日志切换:ALTER SY ...
- SQL Serve里DBA要去改变的3个配置选项
用安装向导安装了全新的SQL Server,最后你点击了完成按钮.哇噢~~~现在我们可以把我们的服务器进入生产了! 抱歉,那并不是真的,因为你的全新SQL Server默认配置是未优化的,一个合格的D ...
- 修改uid gid 的起始范围
UID_MAX 60000 # # Min/max values for automatic gid selection in groupadd # GID_MIN 500 GID_MAX 60000 ...
- gcc-stack-protector机制【转】
转自:https://blog.csdn.net/lhl_blog/article/details/70193865 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上 ...