作者:@小萌新
作者介绍: 非科班大二学生 希望自己能每天输出优质内容
专栏:算法提升之路
由于作者水平有限 所以博客中难免会出现纰漏 希望大佬们看到之后可以指正!> 我们能把握的只有现在 要专心!

一. 二分法的介绍

1. 有序数组中找一个值

题目给你一个有序的数组 要你在这个数组中找一个值 并且返回它的下标 如果找不到就返回-1

这个题目就是一个经典的二分查找运用问题

想一想 假如说给了我们一个有序的数组 我们从头到尾遍历的话 最差的情况下是怎么才会找到这个数呢?

是不是这个数在末尾的时候啊 这个时候的时间复杂度是O(N)

那么这个时候就可以用到我们的二分法

既然说这个数组是有序的 我们假设是这样子

我们从中间开始找

假设这个8是我们的要找的元素的话 我们直接返回这个下标就可以了

假如不是的话 我们比较下这个数和我们要找的数的大小

如果这个数大于我们要找的数 是不是整个数组的右边我们就不要了啊
如果这个数小于我们要找的数 是不是整个数组的左边我们就不要了啊

这样每次减少一半是不是时间复杂度就是Log(N)啊

之后我们继续重复这个过程

直到我们的左下标大于我们的右下标的时候是不是就表明我们要找的这个数不存在啊

我们来看看代码是怎么表示的

int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int sz = sizeof(arr) / sizeof(arr[0]);int k = 0;cin >> k;// 设置左右下标int left = 0;int right = sz - 1;// 循环二分查找int mid = 0;while (left<=right){// mid = (left + right) /2  防止溢出 mid = left + (right - left) / 2;// 判断是否是否等于我们要找的值if (arr[mid]== k){cout << mid;break;}else{if (arr[mid]>k){right = mid - 1;}else{left = mid + 1;}}}return 0;
}

代码也是很简单 简单写一下就可以了

这里注意的有一点

就是关于mid的变化

     // mid = (left + right) /2  防止溢出 mid = left + (right - left) / 2;

此外还可以试试这种写法

     // mid = (left + right) /2  防止溢出 mid = left + ((right - left) / 2 >> 1);// 向左移一位 其实就是相当于除以2

2. 寻找有序数组中大于某个数的位置

给你一个有序数组 要求你找到从某个值开始 后面的所有值都大于我们的key值

这道题目也是一个经典的二分问题 想想看是不是和上面查找某个值的思路很相似啊

我们首先找到中间值

如果这个值大于我们的key值 我们的右边就不要了
如果这个值小于我们的key值 我们的左边就不要了

并且确认它符合条件之后将这个index值记录下来 最后返回用

(我们下面就直接打印index的位置 方便大家理解整个过程)

最后结束的时候 我们直接返回最后记录的一个index位置就好啦

代码表示如下

int main()
{int arr[] = { 1,1,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,8,9,12,13,14,16 };int sz = sizeof(arr) / sizeof(arr[0]);int k = 0;int index = 0;cin >> k;// 设置左右下标int left = 0;int right = sz - 1;// 循环二分查找int mid = 0;while (left <= right){// mid = (left + right) /2  防止溢出 mid = left + (right - left) / 2;// 判断是否是否等于我们要找的值if (arr[mid]>k){index = mid;right = mid - 1;}else{left = mid + 1;}}cout << endl;cout << "找到了 下标位置是:" << index << endl;cout << "值是:" << arr[index] << endl;return 0;
}

整体表示如下

3. 在有序数组中找到小于某个数的位置

思路相似 改变一下大于小于号还有记录index的情况就可以了

代码表示如下

int main()
{int arr[] = { 1,1,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,8,9,12,13,14,16 };int sz = sizeof(arr) / sizeof(arr[0]);int k = 0;int index = 0;cin >> k;// 设置左右下标int left = 0;int right = sz - 1;// 循环二分查找int mid = 0;while (left <= right){// mid = (left + right) /2  防止溢出 mid = left + (right - left) / 2;// 判断是否是否等于我们要找的值if (arr[mid] >= k){right = mid - 1;}else{index = mid;left = mid + 1;}}cout << endl;cout << "找到了 下标位置是:" << index << endl;cout << "值是:" << arr[index] << endl;return 0;
}

运行结果如下

4. 无序数组中寻找一个局部最小值

给你一个无序数组 要求你找到以一个局部最小值

这里的思路用的也是二分法

具体是什么思路呢?

我们来看

我们先比较最前的一个数和后面一个数 如果最前面的一个数小于它后面的一个数 是不是它就是一个局部最小值啊

如果比较了最前面的数和它的后一个数之后发现 它不是一个局部最小值 我们就比较最后面的数和最后面

的数的前面一个数

如果说最后面的数比它前面的一个数要小 那么是不是我们就能够找到最后面一个数是局部最小值啊

如果说上面的两次判断都不满足

那么我们的数组是不是就是一个这样子的状态

那么不管它怎么连 是不是一定会出现一个局部最小值啊


我们还是一样 从中间开始找


假设mid是这个样子的 那么我们是不是可以排除掉右边的一半区域了啊

之后我们继续找左边的二分 是不是继续重复这个步骤啊

代码表示如下

int main()
{int arr[] = { 3,1,5,6,7,5,7,8,1,9 };int sz = sizeof(arr) / sizeof(arr[0]);int left = 0;int right = sz - 1;int mid = 0;int index = 0;// 判断首元素是不是局部最小值 if (arr[left] <= arr[left + 1]){index = left;}// 判断尾元素是不是局部最小值else if (arr[right] <= arr[right - 1]){index = right;goto End;}// 循环开始     while (left<=right){// 这里以及找过了首尾都不是局部最小值 开始二分mid = left + (right - left) / 2;if (arr[mid]<=arr[mid-1]){if (arr[mid] <= arr[mid + 1]){index = mid;break;}else{left = mid + 1;}}else {right = mid - 1;}}End:cout << "找到了 下标位置是:" << index << endl;cout << "值是:" << arr[index] << endl;}

我们只要重复这样简单的循环就能够找到局部最小值啦

演示结果如下

总结


本来想这期给大家带来二分法还有异或的介绍的 但是由于时间的限制只能先写这么多啦
这里给大家简单介绍了下 二分法的几个引用场景
由于博主能力有限 所以难免会出现一些纰漏 希望大佬们看到之后能够指正
阿尼亚 哇库哇库!

算法提升(一)二分法相关推荐

  1. iOS 排序算法总结、二分法查找

    iOS 排序算法总结.二分法查找 还有一个:二分插入排序  平均时间O(n2)   稳定 1.插入排序 在要排序的一组数中,假设前面(n-1) [n>=2] 个数已经是排好顺序的,现在要把第n个 ...

  2. 微分-解卷绕-积分算法提升matlab unwrap函数解卷绕范围

    相位调制的信号,采用IQ数字解调,或者硬件上正交解调的相位,经反正切计算后,phase相位值落在-π到π范围内而不连续.因此,matlab的unwrap函数修正向量phase中的弧度相位角,当phas ...

  3. 算法入门之二分法(LeetCode)

    算法入门之二分法 LeetCode 前言 1. 二分法简介与应用 1.1简介 1.2 应用 1.3 大模板 2. 小模板的构建与分析 2.1小模板内容 2.2 小模板分析 3.案例分析 3.1 案例一 ...

  4. 医学影像 | 谷歌算法提升结肠镜检查的覆盖率, 大幅降低患癌风险

    From: Google  编译: T.R 结肠直肠癌在美国是死亡率第二的癌症.虽然这种疾病非常凶险,但是只要在癌变前诊断出结肠中的癌前病变息肉,并对其进行切除就可以大幅降低患癌风险.然而由于息肉大小 ...

  5. 探索AI视觉技术新应用,夸克扫描王首推“离线模式”端侧AI算法提升隐私安全

    手机扫描正在超越传统扫描仪,给大学生和职场人带来更高效.更便捷的信息服务体验. 在基于手机相机功能的搜索行为中,大学生的学习场景占比超过一半. 手机扫描的"离线模式",让夸克成为第 ...

  6. 技术分享:国民远控向日葵如何通过BBR算法提升远控体验?

    决定远程控制服务体验是否优秀的核心点之一是网络.网络环境优秀时,远程控制的体验自然是高清流畅,但事实上,很多需要应用到远程控制的场景其网络环境远远称不上优秀,在这类弱网环境下如何保证远程控制服务依旧能 ...

  7. 如何借势Facebook广告算法提升内容营销,这里有5个建议

    前言:如何增加Facebook帖子的互动?这个问题困扰着每个内容营销人,Sweta Patel在此提出了5个建议来帮助你做好Facebook内容推广. 你是不是有过类似感觉,Facebook变化太快了 ...

  8. 每周算法讲堂,二分法

    (原文是发送到UESTCACM微信的,所以欢迎大家关注哦~ 大家好,我是萌萌的微信酱! 又到了一周一度难得的周三了哦,你们找到女朋友了吗?喵. 另外你们有没有想我呢? 众人:没有. 呜呜呜呜呜-- ( ...

  9. 百度调整移动搜索排序算法 提升APP排名结果

    百度相关负责人表示,目前用手机访问PC网站难以获得最佳浏览体验,经过此次调整与页面优化,用户将看到更加适应手机屏幕.简洁的搜索页面. 目前,百度针对网站主提供"兼有手机站和PC站" ...

最新文章

  1. java-第十一章-类的无参方法-计算器运算
  2. 如何安装系统认证签名过的APK
  3. Purchase Order Text
  4. python pysnmp使用
  5. k-substrings(CF961F)
  6. 敏捷开发的6个实战经验
  7. 数据和access数据的区别_Access处理数据
  8. 读书随笔:The Book of Why——CHAPTER 1:The Ladder of Causation
  9. 为什么JS中0.1+0.2 != 0.3
  10. Error creating object Microsoft Data Access Components 2.1 (or later) have been properly installed
  11. 【工具使用】apizza和postman中post请求下form-data、x-www-form-urlencoded、raw、binary的区别
  12. 计算机408学什么区别,考研计算机408考什么
  13. C/C++语言IDE_开发工具
  14. 服装尺寸 html,服装尺寸对照表_衣服尺码:M、L、XL、XXL、XXXL 分别代表什么尺码...
  15. php如何实现性格测试,一个很准的性格测试
  16. 2018 11.2 PION模拟赛
  17. 个人项目——二柱子的生成小学生四则运算题程序
  18. 中英文在线语音转文字的方法
  19. envato elements国外设计网站素材代服务包月包年VIP高速下载
  20. [笔记]音视频学习之SDL篇《六》使用SDL_ttf绘制True Type字体

热门文章

  1. python转义字符/a---响铃
  2. 前端网格布局grid
  3. PyTorch中repeat、tile与repeat_interleave的区别
  4. 鸿蒙系统怎么没有微信界面,如果鸿蒙系统没有微信,你会选择用吗?
  5. Errors报错记录
  6. 【软件测试】黑盒测试技术——等价类划分和边界值分析
  7. linux上配置zabbix并设置企业微信,机器人以及自主告警
  8. 拼多多开店不做推广能行吗?
  9. android 涨潮动画加载_潮汐app下载 潮汐 (睡眠白噪音番茄钟) for Android V3.9.1 安卓手机版 下载-脚本之家...
  10. Java运行乱码,Idea编码设置