(图文)二分查找,查指定值、小于或等于k的最大值,大于或等于k的最大值

我们经常会用到二分查找
二分查找应该很多人都会写了,今天要写一个用二分查找找到小于k的最大值的时候看了很久不懂他设计的思路,后来想通了,记录一下。
所以这篇主要是讲 用二分查找找到小于k的最大值大于k的最大值

二分查找查找指定值

这个挺简单的,直接上代码吧

 //获取值是k的位置,找不到则返回-1public static int getK(int[] a, int k){if(a.length == 0){return -1;}int l = 0;int r = a.length - 1;//注意这里的判断条件,是必须允许 l = r 的情况存在的//因为可能会出现刚好到最后左边指针到右边指针只有1个元素,而且这个元素恰恰就是我们想找的kwhile (l <= r){int mid = (l + r) / 2;//如果mid元素已经是k了,那么直接返回if (a[mid] == k){return mid;//查找左边的}else if(a[mid] > k) {r = mid - 1;//查找右边的}else {l = mid + 1;}}//如果没有找到指定的值,那么直接返回-1return -1;}

用二分查找找到小于或者等于k的最大值

思路:如果mid元素是小于或等于k,往右找,如果大于k,往左边找,直到找到一个值,最接近与k的。
看代码中标注了 处地方,下面解释为什么如此设计

    //获取值<=k的最大值public static int uperK(int[] a, int k){int l = 0;int r = a.length - 1;//标注1: 这里是l<r,while(l < r){//标注2: 这样的操作是为了取高位int mid = (l + r + 1) / 2;if(a[mid] <= k) { //标注3:因为a[mid]<=k,所以a[mid]可能=k,所以mid坐标也满足条件,l = mid而不是mid+1;l = mid;}else{r= mid - 1; //这是a[mid] > k的时候。}}//标注4: 因为此时求得到的是最接近于目标值k的数,// 如果最小值都大于k的话,那么就没有办法得到了,所以就进行一个判断if(a[l] > k) return -1;//标注5: 其实这里无论返回 a[l] 还是a[r]都行,循环的退出时间是l == r 的时候return a[l];}
  • 标注1解释:
    因为我们的目的是“通过缩小范围,得到当l = r的时候,l 标记的值”的情况,所以直到 l< r条件被打破的时候的l就是我们要求的值。这跟上一道问题“查找指定值”是不一样的

  • 标注2解释:
    标注2: 这样的操作是为了让 mid 标志 取高位, 才能让循环顺序跳出来,举个死循环的例子
    注意这个例子采取的是mid = (l + r) / 2 取低位的情况,为了展示死循环的形成过程,我们原题的做法是取高位的

数据: int[] num = {1,2,3,4,5,6,7,8,9}, 查找小于或者等于8的最小值。


如上图,此时左坐标是0, 右是8, 那么
mid = (0 + 8) / 2 = 4,num[mid] = num[4] <= k, ,向右找结果,所以有 l = mid,开始下一个循环。


此时的mid = 6, num[6] = 7;
num[mid] <= k, 向右找 l = 6
下一步:

可以得到 l = 6, r = 8, mid = (6+8) / 2 = 7,a[7] = 8 <= k,那么有l = mid = 7, r = 8,
推到得到mid = 7, 问题来了上一步的时候mid已经是7了,结果会使得mid一直是7,一直循环下去。
所以如果我们求的是二分法求小于或者等于k的最大值的话,我们mid 必须取得中值的上界,

  • 标注3解释:
    因为a[mid]<=k,所以a[mid]可能=k,所以mid坐标也满足条件,l = mid而不是mid+1;
  • 标注4解释:
    如果最小值都大于k的话,那么就没有办法得到了,所以就进行一个判断
    最典型的例子是:
    {1,2,3,4,5,6,7,8} ,然后k是0的时候, 这样得到的结果只能是数组中最接近与k的数,但是如果他还是大于k
    你们可以算一下上面这个例子,到最后num[l] 是1, 永远都大于0, 那么得返回取不到值,所以return -1;
  • 标注5解释:
    其实这里无论返回 a[l] 还是a[r]都行,循环的退出时间是l == r 的时候

二分查找大于或等于k的最小值

直接上代码了,想必大家都清楚了,看了上面问题2的解释

public static int downK(List list, int key){while (low < high) {//这里进行的是取低位, 也是为了使得循环可以正确退出,防止死循环int mid = (low + high)/2;if (a[mid] < key) {low = mid +1;} else { //a[mid] >= keyhigh = mid;   //因为mid也满足情况}}//这里进行检查的原因参考上面的标注if (a[high] >= key) {return high;} else {return -1;}
}

二分查找,查指定值、小于或等于k的最大值,大于或等于k的最大值相关推荐

  1. 计算机中最小值的公式,用数组公式在数值列中查找大于指定值的最小值

    在进行产品加工时,需要使用某种原材料,原材料的尺寸是固定的几种类型,其尺寸已在A2:A10中列出,并按升序排列,如图.从节约的角度出发,希望用大于(或等于)产品尺寸的最小值来选择材料.例如产品尺寸为& ...

  2. 考研数据结构之查找(9.8)——练习题之编写一个函数利用二分查找算法在一个有序表中插入关键字k并保持表的有序性(C表示)

    题目 编写一个函数,利用二分查找算法在一个有序表中插入一个关键字k,并保持表的有序性. 分析 先在有序表中利用二分查找算法查找关键字值等于或小于k的结点,m指向正好等于k的结点或l指向关键字正好大于k ...

  3. 二分查找递归与非递归的时间比较_我们说一说Python的查找算法!

    相信大家在面试开发岗和算法岗时,评委最喜欢问的就是:您能给我说一下查找和排序算法有哪些?今天咱们就说一说Python中最常用的查找算法,下期我们再推出排序算法. 首先要明白查找是查什么?我们希望能给定 ...

  4. StringBuffer+排序+二分查找+包装类+正则表达式+常用类

    一.StringBuffer 1.概述 我们如果对字符串进行拼接操作,每次拼接,都会构建一个新的String对象,既耗时,又浪费空间.而StringBuffer就可以解决这个问题StringBuffe ...

  5. 最骚操作的二分查找,秀儿?

    文章目录 你不知道的事 骚算法 测试 测试结果 你不知道的事 你肯定听说过在有序数组中,通过二分算法查找等于指定的值?但是- 你是否听说过在有序数组中,通过二分算法查找大于等于指定的值的最左下标? 你 ...

  6. LeetCode 774. 最小化去加油站的最大距离(极小极大化 二分查找)

    文章目录 1. 题目 2. 解题 1. 题目 假设我们在一条水平数轴上,列表 stations 来表示各个加油站的位置,加油站分别在 stations[0], stations[1], ..., st ...

  7. 二分查找---查找区间

    查找区间 34. Find First and Last Position of Element in Sorted Array Input: nums = [5,7,7,8,8,10], targe ...

  8. leetcode 分享巧克力 java_LeetCode 1231. 分享巧克力(极小极大化 二分查找)

    文章目录 1. 题目 2. 解题 1. 题目 你有一大块巧克力,它由一些甜度不完全相同的小块组成.我们用数组 sweetness 来表示每一小块的甜度. 你打算和 K 名朋友一起分享这块巧克力,所以你 ...

  9. 二分查找算法(Python)

    文章目录 介绍 前提 时间复杂度 原理 介绍 二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法.但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列 ...

最新文章

  1. mybatis plus 插入生成id_springcloud微服务快速教程之分布式ID解决方案(mybatisplus篇)...
  2. spring-java.lang.stackOverFlowError
  3. Python '\r', '\n', '\r\n' 的彻底理解
  4. MSScriptControl详解(可实现在C#等语言中调用JAVASCRIPT代码)
  5. [软件工程基础]结对项目 数独程序扩展
  6. 汇编语言布尔表达式(NOT、AND、OR)
  7. adsl拨号无公网地址如何用ddns_【好玩的网络-第5期】分享自编ddns程序,17行代码轻松实现免费ddns,服务器或nas玩家的福音...
  8. centos 7.0上RabbitMQ 3.5.6版本多实例启动操作讲解
  9. 入门系列之在Ubuntu 16.04使用Buildbot建立持续集成系统
  10. 信息学奥赛C++语言: 商品排序
  11. vs2005常用快捷键_包括代码自动缩进
  12. 【实践】短视频场景下信息流广告的挑战和技术实践.pdf(附下载链接)
  13. ×××背景知识技术介绍
  14. AutoResetEvent类的使用
  15. java clone方法_Java基础:Cloneable接口和Object的clone()方法
  16. java写企业员工信息管理系统
  17. Acid-PEG2000-Pyrene,羧基和芘丁酸修饰的PEG,HOOC-PEG2000-Pyrene
  18. IT学习网站,各大主流网站
  19. matlab正激变换器,12个步骤设计恒流正激式开关电源
  20. BPM就是IT规划与企业战略的最佳匹配

热门文章

  1. 虹软人脸识别中人脸追踪框框运动方向跟实际相反
  2. [移动应用安全]移动应用安全培训PPT
  3. Origin 应用程序无法正常启动(0xc000007b) 错误解决方法(Origin2022)
  4. 使用kms软件激活windows 10企业版
  5. win7计算机桌面快捷键显示桌面,【显示桌面快捷键 win7】显示桌面的快捷键是_win7返回桌面快捷键-系统城...
  6. 转载:应用软件系统架构设计的“七种武器”
  7. 百度地图简单调用js及天气获取
  8. 编写一个函数,从一个字符串中去除多余的空格。
  9. BOM和DOM和事件
  10. iviewUI组件库中select双向绑定不生效