一道简单的面试题:竟然有90%的程序员不能把这个算法完全写正确。。。
前段时间,在论坛上看到有统计说有90%的程序员不能够写对简单的二分法。二分法不是很简单的吗? 这难道不是耸人听闻?
其实,二分法真的不那么简单,尤其是二分法的各个变种。 最最简单的二分法,就是从一个排好序的数组之查找一个key值。 如下面的程序。
/*** 二分查找,找到该值在数组中的下标,否则为-1*/
static int binarySerach(int[] array, int key) {int left = 0;int right = array.length - 1;// 这里必须是 <=while (left <= right) {int mid = (left + right) / 2;if (array[mid] == key) {return mid;}else if (array[mid] < key) {left = mid + 1;}else {right = mid - 1;}}return -1;
}
复制代码
这个程序,相信只要是一个合格的程序员应该都会写。 稍微注意一点, 每次移动left和right指针的时候,需要在mid的基础上+1或者-1, 防止出现死循环, 程序也就能够正确的运行。
但如果条件稍微变化一下, 你还会写吗?如,数组之中的数据可能可以重复,要求返回匹配的数据的最小(或最大)的下标;更近一步, 需要找出数组中第一个大于key的元素(也就是最小的大于key的元素的)下标,等等。 这些,虽然只有一点点的变化,实现的时候确实要更加的细心。 下面列出了这些二分检索变种的实现。
1、找出第一个与key相等的元素
// 查找第一个相等的元素
static int findFirstEqual(int[] array, int key) {int left = 0;int right = array.length - 1;// 这里必须是 <=while (left <= right) {int mid = (left + right) / 2;if (array[mid] >= key) {right = mid - 1;}else {left = mid + 1;}}if (left < array.length && array[left] == key) {return left;}return -1;
}
复制代码
2、找出最后一个与key相等的元素
// 查找最后一个相等的元素
static int findLastEqual(int[] array, int key) {int left = 0;int right = array.length - 1;// 这里必须是 <=while (left <= right) {int mid = (left + right) / 2;if (array[mid] <= key) {left = mid + 1;}else {right = mid - 1;}}if (right >= 0 && array[right] == key) {return right;}return -1;
}
复制代码
3、查找第一个等于或者大于Key的元素
// 查找第一个等于或者大于key的元素
static int findFirstEqualLarger(int[] array, int key) {int left = 0;int right = array.length - 1;// 这里必须是 <=while (left <= right) {int mid = (left + right) / 2;if (array[mid] >= key) {right = mid - 1;}else {left = mid + 1;}}return left;
}
复制代码
4、查找第一个大于key的元素
// 查找第一个大于key的元素
static int findFirstLarger(int[] array, int key) {int left = 0;int right = array.length - 1;// 这里必须是 <=while (left <= right) {int mid = (left + right) / 2;if (array[mid] > key) {right = mid - 1;}else {left = mid + 1;}}return left;
}
复制代码
5、查找最后一个等于或者小于key的元素
// 查找最后一个等于或者小于key的元素
static int findLastEqualSmaller(int[] array, int key) {int left = 0;int right = array.length - 1;// 这里必须是 <=while (left <= right) {int mid = (left + right) / 2;if (array[mid] > key) {right = mid - 1;}else {left = mid + 1;}}return right;
}
复制代码
6、查找最后一个小于key的元素
// 查找最后一个小于key的元素
static int findLastSmaller(int[] array, int key) {int left = 0;int right = array.length - 1;// 这里必须是 <=while (left <= right) {int mid = (left + right) / 2;if (array[mid] >= key) {right = mid - 1;}else {left = mid + 1;}}return right;
}
复制代码
接下来,大家可以对这四种变种算法进行相应的测试。
很多的时候,应用二分检索的地方都不是直接的查找和key相等的元素,而是使用上面提到的二分检索的各个变种,熟练掌握了这些变种,当你再次使用二分检索的检索的时候就会感觉的更加的得心应手了。
一道简单的面试题:竟然有90%的程序员不能把这个算法完全写正确。。。相关推荐
- 真实揭秘90后程序员婚恋现状,有点扎心!
导读:目前,90后已经成为婚恋市场的主力军,且在互联网占据人们大部分的生活和工作的当下,90后"找对象"的方式也互联网化:据有缘网<90后大众婚恋行为报告2019>报告 ...
- Spring AOP注解为什么失效?90%Java程序员不知道
转载自 Spring AOP注解为什么失效?90%Java程序员不知道 使用Spring Aop注解的时候,如@Transactional, @Cacheable等注解一般需要在类方法第一个入口的地方 ...
- 这里90%的程序员根本就不算程序员。
csdn真的很红火,很不错,中国有很多程序员. 并且还有很多人过几年就要成为程序员. 有的人说,IT行业是热门行业,有的人说,IT业干的那么苦,工资那么低. 有的人说,我们找不到工作,有人说, ...
- 90 后程序员薪资大揭秘:有人刚毕业年薪 200 万,有人月薪不足 1 万
作者 | 素年清时 责编 | 伍杏玲 出品 | 程序人生(ID:coder_life) 相信大家最近都被华为给几名新员工开出的巨额工资给刷屏了,根据任正非签发的一份总裁办电子邮件,华为对八名 2019 ...
- 90后程序员已经出家了
作者:路人甲 最近佛系这个词很火,所谓佛系大概意思就是:有也行,没有也行,不争不抢,不求输赢!作为我们90后程序员,我们在日常工作生活中,也都会有这样的转变,从一些小事的斤斤计较到不计较得失. 于是我 ...
- 卖饭考公当老板,第一批 90 后程序员的转行之路
都说程序员是碗青春饭,过了三十便不再吃香.眼看第一批90后程序员马上就是三十岁了,随着门槛值的日益逼近,他们是否已经开始为此犯愁并准备谋划出路了呢? 本文采访了几位转行成功的90后程序员,让我们来听听 ...
- 《90后程序员职场报告》:平均月薪近20K,每6个程序员就有1个是女性
点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 作者 | 拉勾 来源 | 公众号「拉勾」(lagounews) 第一批90后已经快30了.9 ...
- 工作中这些实用的小技巧,90%的程序员不知道
工作中这些实用的小技巧,90%的程序员不知道 Linux 有些Linux命令我们是经常用的,但是这些命令有的特别长(如进入层级特别深的项目部署目录),这时就可以为这些命令定义一个别名 系统级别定义的别 ...
- 90 % Java 程序员被误导的一个性能优化策略
转载自 90 % Java 程序员被误导的一个性能优化策略 我们经常看到一些 Java 性能优化的书或者理念,说不要在循环内定义变量,这样会占用过多的内存影响性能,而要在循环外面定义.接触 Jav ...
最新文章
- CSS盒模型及边距问题
- 面试都在问的微服务,一文带你彻底搞懂!
- Linux下Keepalived安装与配置
- Java 基础 - 面向对象(不错N多教程集合)
- 2019/Province_C_C++_A/B/数列求值
- 设计模式初探之模板方法(Template Method)
- java通过commons-fileupload实现多张图片的上传(servlet)
- 用编程语言和计算机沟通
- H3C模拟器simware搭建总结
- 爬虫mm131明星照片
- AB变频器常见故障的原因及处理方法
- 使用32驱动1602液晶屏
- 无卡支付系统(德齐互联)
- 数学建模学习(7):分支结构与循环结构详解
- 实验题目:约瑟夫环问题:设编号为1,2,3,……,n的n(n>0)个人按顺时针方向围坐一圈,m为任意一个正整数。从第一个人开始顺时针方向自1起顺序报数,报到m时停止并且报m的人出列,再从他的下一个人
- 农历 Android Java 节气_Android自定义日历,可以点击、标注日期、节气、旧历等
- Typora+图床详解(小白都能学得会)
- 《机器学习》周志华第10章降维与度量学习 思维导图+笔记+习题
- Leetcode 999. Available Captures for Rook
- 选硬盘时,该选择SSD/SATA/SAS哪个好?