算法设计思想(6)— 二分法(二分法代码模板、寻找左侧边界二分法、寻找右侧边界二分法)
1. 问题
【例题】循环输入,每组数据为给定 n 个元素的升序整型数组 nums 和一个值 target,要求实现一个函数查找 nums 中 target 的下标,如果查找不到则返回 -1.
2. 思路
3. 代码
int find(int n, int a[], int target)
{int l = 0;int r = n - 1;while (l <= r){int middle = (l + r) / 2;if (a[middle] < target){l = middle + 1;}else if (a[middle] > target){r = middle - 1;}else{return middle;}}return -1;
}int main()
{int n, target, ret;std::cout << "input number of n " << std::endl;while (std::cin >> n){int b[n] = {0};for (int i = 0; i < n; i++){std::cin >> b[i];}std::cout << "input target " << std::endl;std::cin >> target;ret = find(n, b, target);std::cout << "location:" << ret << std::endl;}return 0;
}
4. 二分法模板
二分搜索的一个技巧:不要出现 else
,而是把所有的情况用 else if
写清楚,因为这样可以清楚的展现所有的细节。
func binarySearch(a []int, target int) int {left := 0right := len(a) - 1// 因为搜素区间是 [left, right],左右都是封闭的,所以循环时应该是 <=for left <= right {mid := left + (right-left)/2if a[mid] == target {return mid} else if a[mid] < target {left = mid + 1} else if a[mid] > target {right = mid - 1}}return -1
}
5. 寻找左侧边界的二分法
package mainimport ("fmt"
)func leftBinarySearch(a []int, target int) int {left := 0right := len(a) - 1// 因为搜素区间是 [left, right],左右都是封闭的,所以循环时应该是 <=for left <= right {mid := left + (right-left)/2if a[mid] == target {// 不要返回,收缩右边界,逐步锁定左侧边界right = mid - 1} else if a[mid] < target {left = mid + 1} else if a[mid] > target {right = mid - 1}}// 上面循环结束时 left = right + 1 ,所以当 target 比 a 中所有元素都大时,// 会存在 left 越界的情况if left >= len(a) || a[left] != target {return -1}return left
}func main() {arr := []int{1, 2, 3, 4, 4, 7, 7, 8, 9}fmt.Println(leftBinarySearch(arr, 4))
}
6. 寻找右侧边界的二分法
package mainimport ("fmt"
)func rightBinarySearch(a []int, target int) int {left := 0right := len(a) - 1// 因为搜素区间是 [left, right],左右都是封闭的,所以循环时应该是 <=for left <= right {mid := left + (right-left)/2if a[mid] == target {// 不要返回,收缩左边界,逐步锁定右侧边界left = mid + 1} else if a[mid] < target {left = mid + 1} else if a[mid] > target {right = mid - 1}}// 上面循环结束时 left = right + 1 ,所以当 target 比 a 中所有元素都小时,// right 会被减小到 -1,会存在 right 越界的情况if right < 0 || a[right] != target {return -1}return right
}func main() {arr := []int{1, 2, 3, 4, 4, 7, 7, 8, 9}fmt.Println(rightBinarySearch(arr, 4))
}
算法设计思想(6)— 二分法(二分法代码模板、寻找左侧边界二分法、寻找右侧边界二分法)相关推荐
- (十五)算法设计思想之“回溯算法”
算法设计思想之"回溯算法" 回溯算法是什么? 什么问题适合用回溯算法解决? 适合回溯算法解决的问题 全排列 LeetCode:46.全排列 LeetCode:78.子集 思考题 回 ...
- (十四)算法设计思想之“贪心算法”
算法设计思想之"贪心算法" 贪心算法是什么 LeetCode:455.分饼干 LeetCode:122.买卖股票的最佳时机II 思考题 贪心算法是什么 贪心算法是算法设计中的一种方 ...
- (十三)算法设计思想之“动态规划”
算法设计思想之"动态规划" 动态规划是什么? 动态规划的步骤 LeetCode:70.爬楼梯 LeetCode:198.打家劫舍 思考题 动态规划是什么? 动态规划是算法设计中的一 ...
- (十二)算法设计思想之“分而治之”
算法设计思想之"分而治之" 分而治之是是什么 场景一:归并排序 场景二:快速排序 LeetCode:374.猜数字大小 LeetCode:226.翻转二叉树 LeetCode:10 ...
- 算法设计与分析_[04] 天牛须算法设计思想分析
原文链接: https://arxiv.org/abs/1710.10724arxiv.org 算法实现: 首先,初始化参数 ,分别代表初始解,初始的搜索范围,以及更新步长,且通过原文我们知道: 在 ...
- 五大算法设计思想,你都知道吗?
作者:叫我不矜持 链接:https://www.jianshu.com/p/bf8b0668d191 一.分治法 1.概念: 将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分 ...
- 求一个任意实数c的算术平方根g的算法设计思想_算法复习第四篇——贪心法
公元2020年5月5日,距离算法考试仅剩4天. 一.知识归纳 1.设计思想 只根据当前已有的信息就做出选择,而且一旦做出了选择,将来无论如何都不能更改 不从整体最优考虑,所做的选择只是在某种意义上的局 ...
- 算法设计思想(2)— 贪婪法
1. 贪婪法定义 贪婪法,又称贪心算法,是寻找最优解问题的常用方法,这种方法模式一般将求解过程分成若干个步骤,但每个步骤都应用贪心原则,选取当前状态下最好的或最优的选择(局部最有利的选择),并以此希望 ...
- 算法设计思想(5)— 递归法
1. 递归概念 递归 Recursion是指在函数的定义中使用函数自身的方法,直观上来看,就是某个函数自己调用自己. 递归有两层含义: 递归问题必须可以分解为若干个规模较小.与原问题形式相同的子问 ...
最新文章
- STS中applicationContext.xml配置文件
- Digital Signage and Windows Embedded Standard 7
- pyqt 照片打上水印
- 强监管下 协议支付会是互金平台救命稻草?(协议支付是代扣协议的升级版)
- Tomcat7源码分析学习系列之二-----tomcat的真正的启动脚本catalina.bat解析
- RTSP学习笔记(2)live555
- Python学习笔记:安装python
- php 出错处理,PHP 错误处理机制
- r语言折线图_R语言做多变量可视化分析?
- 深入了解JavaScript目录(持续更新)
- 设计模式经典书籍推荐
- 软件项目管理第十章笔记---项目采购管理
- flutter 上滑悬浮吸顶
- DDD案例(2):从领域分析到代码实现
- 绿皮车里的温馨服务 情暖回家路
- Mooc_AutoCAD绘制建筑施工图_单元平面图测验题
- 数字科技行业的“挖井人”:京东数科不做一锤子买卖
- 单片机:数字式时钟—日历
- 使用switch语句根据消费金额计算折扣
- 2023新版微信九块九进群系统源码+全解的