前段时间,在论坛上看到有统计说有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%的程序员不能把这个算法完全写正确。。。相关推荐

  1. 真实揭秘90后程序员婚恋现状,有点扎心!

    导读:目前,90后已经成为婚恋市场的主力军,且在互联网占据人们大部分的生活和工作的当下,90后"找对象"的方式也互联网化:据有缘网<90后大众婚恋行为报告2019>报告 ...

  2. Spring AOP注解为什么失效?90%Java程序员不知道

    转载自 Spring AOP注解为什么失效?90%Java程序员不知道 使用Spring Aop注解的时候,如@Transactional, @Cacheable等注解一般需要在类方法第一个入口的地方 ...

  3. 这里90%的程序员根本就不算程序员。

    csdn真的很红火,很不错,中国有很多程序员.   并且还有很多人过几年就要成为程序员. 有的人说,IT行业是热门行业,有的人说,IT业干的那么苦,工资那么低.   有的人说,我们找不到工作,有人说, ...

  4. 90 后程序员薪资大揭秘:有人刚毕业年薪 200 万,有人月薪不足 1 万

    作者 | 素年清时 责编 | 伍杏玲 出品 | 程序人生(ID:coder_life) 相信大家最近都被华为给几名新员工开出的巨额工资给刷屏了,根据任正非签发的一份总裁办电子邮件,华为对八名 2019 ...

  5. 90后程序员已经出家了

    作者:路人甲 最近佛系这个词很火,所谓佛系大概意思就是:有也行,没有也行,不争不抢,不求输赢!作为我们90后程序员,我们在日常工作生活中,也都会有这样的转变,从一些小事的斤斤计较到不计较得失. 于是我 ...

  6. 卖饭考公当老板,第一批 90 后程序员的转行之路

    都说程序员是碗青春饭,过了三十便不再吃香.眼看第一批90后程序员马上就是三十岁了,随着门槛值的日益逼近,他们是否已经开始为此犯愁并准备谋划出路了呢? 本文采访了几位转行成功的90后程序员,让我们来听听 ...

  7. 《90后程序员职场报告》:平均月薪近20K,每6个程序员就有1个是女性

    点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 作者 | 拉勾 来源 | 公众号「拉勾」(lagounews) 第一批90后已经快30了.9 ...

  8. 工作中这些实用的小技巧,90%的程序员不知道

    工作中这些实用的小技巧,90%的程序员不知道 Linux 有些Linux命令我们是经常用的,但是这些命令有的特别长(如进入层级特别深的项目部署目录),这时就可以为这些命令定义一个别名 系统级别定义的别 ...

  9. 90 % Java 程序员被误导的一个性能优化策略

    转载自   90 % Java 程序员被误导的一个性能优化策略 我们经常看到一些 Java 性能优化的书或者理念,说不要在循环内定义变量,这样会占用过多的内存影响性能,而要在循环外面定义.接触 Jav ...

最新文章

  1. CSS盒模型及边距问题
  2. 面试都在问的微服务,一文带你彻底搞懂!
  3. Linux下Keepalived安装与配置
  4. Java 基础 - 面向对象(不错N多教程集合)
  5. 2019/Province_C_C++_A/B/数列求值
  6. 设计模式初探之模板方法(Template Method)
  7. java通过commons-fileupload实现多张图片的上传(servlet)
  8. 用编程语言和计算机沟通
  9. H3C模拟器simware搭建总结
  10. 爬虫mm131明星照片
  11. AB变频器常见故障的原因及处理方法
  12. 使用32驱动1602液晶屏
  13. 无卡支付系统(德齐互联)
  14. 数学建模学习(7):分支结构与循环结构详解
  15. 实验题目:约瑟夫环问题:设编号为1,2,3,……,n的n(n>0)个人按顺时针方向围坐一圈,m为任意一个正整数。从第一个人开始顺时针方向自1起顺序报数,报到m时停止并且报m的人出列,再从他的下一个人
  16. 农历 Android Java 节气_Android自定义日历,可以点击、标注日期、节气、旧历等
  17. Typora+图床详解(小白都能学得会)
  18. 《机器学习》周志华第10章降维与度量学习 思维导图+笔记+习题
  19. Leetcode 999. Available Captures for Rook
  20. 选硬盘时,该选择SSD/SATA/SAS哪个好?

热门文章

  1. Android中获取系统语言(适用于Android7.0以上系统)
  2. iOS网络开发之:NSURLConnection
  3. oracle 禁用外键
  4. 挑选管理软件应注意的几个问题
  5. oracle数据库学习相关笔记-转换函数
  6. Servlet + JSP(EL表达式)
  7. mysql mysqld_multi 单机多进程
  8. SQL中的Null值
  9. boost之Boost.Foreach遍历
  10. 一招解决迅雷5不更新无法继续使用原创