面试官,我会写二分查找法!对,没有 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 ...
随机推荐
- IT兄弟连 HTML5教程 设置IE9以下版本浏览器支持HTML5
HTML2.HTML5刚发布时由于各浏览器之间的标准不统一,开发者的时间都浪费在解决Web浏览器之间的兼容性上.但由于W3C和WHATWG对HTML5新版本的制定,以及近年来对HTML5的使用,再加上 ...
- 解决python安装第三方库超时问题
这里说明一下,配置文件中的url还可以换成下面的URL 阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.u ...
- 当h5页面图片加载失败后,给定一个默认图
本文主要讨论页面中图片加载失败后替换默认图片的几种方式 重点来了:一定要记住error事件不冒泡. 相关的知识点:jquery的ready方法.$("img").error().i ...
- Maven 教程之 pom.xml 详解
作者:dunwu https://github.com/dunwu/blog 推荐阅读(点击即可跳转阅读) 1. SpringBoot内容聚合 2. 面试题内容聚合 3. 设计模式内容聚合 4. My ...
- 痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU特性那些事(1)- 概览
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RTyyyy系列MCU的基本特性. ARM Cortex-M微控制器芯片厂商向来竞争激烈,具体可参看我的另一篇文章&l ...
- 软件设计之基于Java的连连看小游戏(一)——开题及游戏首页的制作
原本计划紧张忙碌的考试月在图书馆和实验室度过,结果突如其来为期两周的软件设计把课余时间几乎捆绑在了机房.软设没有太多知识上的要求,只要成品简洁美观.实用准确即可.考虑了很久决定要用Java swing ...
- 如何搭建node - express 项目
基于博主也是个菜鸟,亲身体验后步骤如下: 首先,我们需要安装node.js, https://www.runoob.com/nodejs/nodejs-install-setup.html 安装完成 ...
- GitHub访问速度慢的一种优化方法
GitHub是一个面向开源及私有软件项目的托管平台,因为只支持Git 作为唯一的版本库格式进行托管,故名GitHub. 由于GitHub是一个国外网站,在国内访问速度如何呢? 我们通过浏览器访问下ht ...
- 3-SQL过滤
# 筛选最大生命值大于6000,最大法力值大1700的英雄,然后按照二者之和从高到低进行排序 SELECT NAME , hp_max, mp_max FROM he ...
- MySQL 57安装部署(Zip版)(Windows版)
1. 在<MYSQL>的根目录下新建一个my.ini写入以下内容 [mysqld] port = 3306 basedir=D:\mysql\mysql-5.7.22-winx64 # M ...