图解 LeetCode 算法汇总——二分查找
二分查找(Binary Search)是一种在有序数组中查找特定元素的高效算法。它的基本思想是将目标值与数组中间的元素进行比较,如果目标值小于中间元素,则在数组的左半部分继续查找,否则在右半部分查找,不断缩小搜索范围,直到找到目标值或确定目标值不存在为止。
二分查找也叫折半查找,比如在一个有序的数组里面找到目标值,它是一种查询效率比较高的算法,时间复杂度O(logn)。比如在下面数组找到 6.首先在定位到两侧,也就是最大值和最小值。并找到中间和目标值比较。

中间值是 23,比目标值更大,就要缩小范围,中间值作为最大值,在中间值左边的区域再找到中间值和目标值比较。

以此类推,一直缩小范围,直到找到目标值,或者搜索完数据。
二分查找模板
public static int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2; // 计算中间元素的索引
if (nums[mid] == target) {
return mid; // 找到目标值,返回索引
} else if (nums[mid] < target) {
left = mid + 1; // 目标值在右半部分
} else {
right = mid - 1; // 目标值在左半部分
}
}
return -1; // 目标值不存在
}
left 和 right 记录最小值和最大值的下标,left + (right - left) / 2 是查询中间下标,有的查询下标直接使用(left + right)/2,这样可能会超出时间范围。通过 left = mid + 1 或者 right = mid - 1 不断缩小范围。
LeetCode 题解
33.搜索旋转排序数组
题目描述

解题思路
有序的数组在某个下标上进行旋转:

将旋转点之后的数据整体放在数组之前:

上面说二分查询只是针对有序的数组,这又不是一个有序的数组,但是数组分成两部分有序的数组。

- 使用二分查找查看由 mid 分割出来的两部分 [l,mid] 和 [mid+1,r] 哪个部分是有序的,并根据有序的那个部分确定二分查找的左右边界
- 如果[l,m-1]是有序数组,并且 target 的大小在 [l,mid] 中,则将搜索目标缩小至[l,mid - 1],否则范围在 [mid + 1,r] 中寻找。
- 如果[mid,r]是有序数组,并且 target 的大小在 [mid + 1,r] 中,则将搜索目标缩小至[mid + 1,r],否则在[l,mid - 1] 中寻找。
public int search(int[] nums, int target) {
int length = nums.length;
if (length == 0) {
return -1;
}
if (length == 1) {
return nums[0] == target ? 0 : -1;
}
int left = 0,right = length-1;
while (left <= right) {
int mid = left + (right - left)/2;
if (nums[mid] == target) {
return mid;
}
if (nums[0] <= nums[mid]) {
if (nums[0] <= target && target < nums[mid]) {
right = mid -1;
} else {
left = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[length - 1]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return -1;
}
69.x的平方根
题目描述

解题思路
求解平法根,也就是k² <= x,也就是求解 k 最大整数值。对 x 进行二分查找。
- 左边界是0,右边界是为x,每次二分查找到中间值 mid,mid 的平方的 x 的大小做对比。
- 如果 mid 的平方小于等于 x,赋值结果,并且左边界移动到 mid + 1 的位置。
- 如果 mid 的平方大于x,将有边界移动到 mid - 1 的位置。
- 直达找到最优的解。
public int mySqrt(int x) {
if (x == 0 || x == 1) {
return x;
}
int left = 1;
int right = x;
int result = -1;
while (left <= right) {
int mid = left + (right - left)/2;
if ((long)mid * mid > x) {
right = mid - 1;
} else {
result = mid;
left = mid + 1;
}
}
return result;
}
153.寻找旋转排序数组中的最小值
题目描述

解题思路
旋转数组是要么全部有序,要么两个部分有序。每次做二分查找,每次mid和最右边值作比较,会出现两种情况。

第一种情况是 nums[pivot] < nums[high],如上图所示,此时最小值应该在 piot 的左侧,height 缩进到 pivot 的位置。

第二种情况是 nums[piot] > num[height], 如上图所示,此时最小值应该在 piot 的右侧,low 缩进到 piot 的位置。
class Solution {
public int findMin(int[] nums) {
int low = 0,height = nums.length-1;
while (low < height) {
int mid = low + (height - low)/2;
if (nums[mid] < nums[height]) {
height = mid;
} else {
low = mid + 1;
}
}
return nums[low];
}
}
367.有效的完全平方数
题目描述

解题思路
- 判断一个数是否是完全平方数,需要找到他的开根数。
- 使用二分法查找,如果 num < 2 返回true,因为 0 和都是完全平方数。
- 2 为 left,num 为 right,通过 left + (right - left)/2 找到中间值
- 如果 mid² = num,返回true。
- 如果 mid² < num,left = mid + 1。
- 如果 mid² > num ,right = mid - 1。
public boolean isPerfectSquare(int num) {
if (num <= 2) {
return true;
}
int left = 2,right = num/2,y;
long square;
while (left <= right) {
y = left + (right - left)/2;
square =(long) y * y;
if (square == num) {
return true;
}else if (square > num) {
right = y - 1;
}else {
left = y + 1;
}
}
return false;
}
总结
搜索有序的数组的元素,使用二分查找是一个高效率的查询方法。定位左右两侧最大值和最小值,找到中间值。然后通过目标值和中间值做对比,缩小搜索范围,直到搜索找到符合条件数据。
有时候无需全部有序,两部分有序也是可以通过二分查找找到符合要求的数据。
图解 LeetCode 算法汇总——二分查找的更多相关文章
- 【算法】二分查找法&大O表示法
二分查找 基本概念 二分查找是一种算法,其输入是一个有序的元素列表.如果要查找的元素包含在列表中,二分查找返回其位置:否则返回null. 使用二分查找时,每次都排除一半的数字 对于包含n个元素的列表, ...
- javascript数据结构与算法---检索算法(二分查找法、计算重复次数)
javascript数据结构与算法---检索算法(二分查找法.计算重复次数) /*只需要查找元素是否存在数组,可以先将数组排序,再使用二分查找法*/ function qSort(arr){ if ( ...
- 分治算法(二分查找)、STL函数库的应用第五弹——二分函数
分治算法:二分查找!昨天刚说不写算法了,但是突然想起来没写过分治算法的博客,所以强迫症的我…… STL函数库第五弹——二分函数lower_bound().upper_bound().binary_se ...
- 算法图解第一章_二分查找_python
什么是二分查找? 我们先玩一个游戏. 在1至100之间我写下一个数,由你来猜测这个数是多少.我会告诉你高了还是低了. 最简单的办法就是每次取一半. 例如 "50""低了& ...
- 算法图解 - 第1章 二分查找 与大O
例子:猜一个1到100之间的数,最多猜几次? # 最糟糕的猜法:一个一个的猜 - 最多查找次数: n - 运行时间: O(n) # 二分查找:在有序的一组数中猜一个数,对半猜.找到返回其位置(索引) ...
- python算法之二分查找
说明:大部分代码是在网上找到的,好几个代码思路总结出来的 通常写算法,习惯用C语言写,显得思路清晰.可是假设一旦把思路确定下来,并且又不想打草稿.想高速写下来看看效果,还是python写的比較快.也看 ...
- JS算法之二分查找
二分查找法主要是解决「在一堆有序的数中找出指定的数」这类问题,不管这些数是一维数组还是 多维数组,只要有序,就可以用二分查找来优化. 二分查找是一种「分治」思想的算法,大概流程如下: 1.数组中排在中 ...
- 数据结构与算法之PHP查找算法(二分查找)
二分查找又称折半查找,只对有序的数组有效. 优点是比较次数少,查找速度快,平均性能好,占用系统内存较少: 缺点是要求待查表为有序表,且插入删除困难. 因此,折半查找方法适用于不经常变动而查找频繁的有序 ...
- python实现查找算法:二分查找法
二分查找算法也称折半查找,基本思想就是折半,和平时猜数字游戏一样,比如猜的数字时67,猜测范围是0-100,则会先猜测中间值50,结果小了,所以就会从50-100猜测,中间值为75,结果大了,又从50 ...
- Java查找算法之二分查找
二分查找是一种查询效率非常高的查找算法.又称折半查找. 一.算法思想 有序的序列,每次都是以序列的中间位置的数来与待查找的关键字进行比较,每次缩小一半的查找范围,直到匹配成功. 一个情景:将表中间位置 ...
随机推荐
- 苹果WWDC发布会总结
今年的全球开发者大会没有让人失望.在今天的主题演讲中,苹果首次展示了备受期待的混合现实耳机,证实了过去几个月出现的许多谣言. 虽然这次苹果的 Vision Pro耳机成为了焦点,但该公司还发布了一些其 ...
- 深度学习应用篇-推荐系统[12]:经典模型-DeepFM模型、DSSM模型召回排序策略以及和其他模型对比
深度学习应用篇-推荐系统[12]:经典模型-DeepFM模型.DSSM模型召回排序策略以及和其他模型对比 1.DeepFM模型 1.1.模型简介 CTR预估是目前推荐系统的核心技术,其目标是预估用户点 ...
- 如何在 Python 中实现遗传算法
前言 遗传算法是一种模拟自然进化过程与机制来搜索最优解的方法,它由美国 John Holland 教授于20世纪70年代提出.遗传算法的主要思想来源于达尔文生物进化论和孟德尔的群体遗传学说,通过数学的 ...
- Kubernetes 1.27.2集群安装
基础环境 系统Ubuntu 22.04.2 | 主机名称 | IP | | ----- | -------- | | k8s-master | 192.168.198.141 | | k8s-node ...
- ChatGPT:免费在线聊天网页版,探索智能人机交互的便捷新方式!
当今,机器智能相当流行.而在线人工智能聊天系统的兴起大大改变了我们与计算机互动的方式.本文将介绍一款名为 ChatGPT 的在线免费智能聊天网页版,让你体验智能对话的便利性. ChatGPT 是一种基 ...
- FPGA加速技术:如何提高系统的可编程性和灵活性
目录 <23. FPGA加速技术:如何提高系统的可编程性和灵活性> 一.引言 随着人工智能.物联网等新技术的快速发展,对计算资源和处理能力的需求不断增加.为了加速计算流程和提高系统的性能, ...
- hashtable分析
1.什么是Hash表? Hash表又被称为散列表,是根据关键码值(key-value)也就是键值对来直接访问的一种数据结构.也就是说,它通过把关键码值映射到表中的一个位置来访问记录,用以加快查找的 ...
- ERP导出(自定义格式表格)R报表开发代码
按照正常流程新建程序,画面修改上传,程序下载修改 导入JAVA包,在global.import下 IMPORT com IMPORT JAVA java.net.URL IMPORT JAVA org ...
- gowWeb之错误处理和返回响应
Go Web开发进阶实战(gin框架) 讲师:李文周老师 https://study.163.com/course/introduction.htm?courseId=1210171207&t ...
- requests的基础使用
爬虫介绍 # 爬虫:又称网络蜘蛛,spider,一堆程序,从互联网中抓取数据---->数据清洗---->入库 # 爬虫需要掌握的知识 -抓取数据:发送网络请求(http),获得响应(htt ...