二分查找(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 算法汇总——二分查找的更多相关文章

  1. 【算法】二分查找法&大O表示法

    二分查找 基本概念 二分查找是一种算法,其输入是一个有序的元素列表.如果要查找的元素包含在列表中,二分查找返回其位置:否则返回null. 使用二分查找时,每次都排除一半的数字 对于包含n个元素的列表, ...

  2. javascript数据结构与算法---检索算法(二分查找法、计算重复次数)

    javascript数据结构与算法---检索算法(二分查找法.计算重复次数) /*只需要查找元素是否存在数组,可以先将数组排序,再使用二分查找法*/ function qSort(arr){ if ( ...

  3. 分治算法(二分查找)、STL函数库的应用第五弹——二分函数

    分治算法:二分查找!昨天刚说不写算法了,但是突然想起来没写过分治算法的博客,所以强迫症的我…… STL函数库第五弹——二分函数lower_bound().upper_bound().binary_se ...

  4. 算法图解第一章_二分查找_python

    什么是二分查找? 我们先玩一个游戏. 在1至100之间我写下一个数,由你来猜测这个数是多少.我会告诉你高了还是低了. 最简单的办法就是每次取一半. 例如 "50""低了& ...

  5. 算法图解 - 第1章 二分查找 与大O

    例子:猜一个1到100之间的数,最多猜几次? # 最糟糕的猜法:一个一个的猜 - 最多查找次数: n  - 运行时间: O(n) # 二分查找:在有序的一组数中猜一个数,对半猜.找到返回其位置(索引) ...

  6. python算法之二分查找

    说明:大部分代码是在网上找到的,好几个代码思路总结出来的 通常写算法,习惯用C语言写,显得思路清晰.可是假设一旦把思路确定下来,并且又不想打草稿.想高速写下来看看效果,还是python写的比較快.也看 ...

  7. JS算法之二分查找

    二分查找法主要是解决「在一堆有序的数中找出指定的数」这类问题,不管这些数是一维数组还是 多维数组,只要有序,就可以用二分查找来优化. 二分查找是一种「分治」思想的算法,大概流程如下: 1.数组中排在中 ...

  8. 数据结构与算法之PHP查找算法(二分查找)

    二分查找又称折半查找,只对有序的数组有效. 优点是比较次数少,查找速度快,平均性能好,占用系统内存较少: 缺点是要求待查表为有序表,且插入删除困难. 因此,折半查找方法适用于不经常变动而查找频繁的有序 ...

  9. python实现查找算法:二分查找法

    二分查找算法也称折半查找,基本思想就是折半,和平时猜数字游戏一样,比如猜的数字时67,猜测范围是0-100,则会先猜测中间值50,结果小了,所以就会从50-100猜测,中间值为75,结果大了,又从50 ...

  10. Java查找算法之二分查找

    二分查找是一种查询效率非常高的查找算法.又称折半查找. 一.算法思想 有序的序列,每次都是以序列的中间位置的数来与待查找的关键字进行比较,每次缩小一半的查找范围,直到匹配成功. 一个情景:将表中间位置 ...

随机推荐

  1. python selenium框架解决ip代理框不能自动化登录,解决pyautogui开不了多线程问题

    有时候我们使用python自动化框架的时候,打开一个网页的时候,它会出现出线这一种登录框,我们f12检查不了,用开发者工具强制检查里面没有任何属性. 那这时候我们就可以用到python第三方库:pya ...

  2. 专访泛境科技:如何借助3DCAT实时云渲染打造元宇宙解决方案

    随着5G.VR/AR等技术的发展,元宇宙(Metaverse)这一概念越来越受到关注.元宇宙是一个由虚拟世界构成的网络空间,其中人们可以通过数字化的身份和形象进行各种社交.娱乐.创作和商业活动.元宇宙 ...

  3. mybatis拦截器实现数据权限

    前端的菜单和按钮权限都可以通过配置来实现,但很多时候,后台查询数据库数据的权限需要通过手动添加SQL来实现. 比如员工打卡记录表,有id,name,dpt_id,company_id等字段,后两个表示 ...

  4. Python生成指定大小的文件

    转载请注明出处️ 作者:测试蔡坨坨 原文链接:caituotuo.top/400bd75c.html 你好,我是测试蔡坨坨. 在日常测试工作中,我们经常需要对上传的文件大小进行测试,例如:一个文件上传 ...

  5. STM32低功耗配置

    一.相关介绍 1.1 STM32下的电源管理 电源框图 电源标号说明 电压调节器 复位后调节器总是使能.以3种不同的模式工作. 运转模式:调节器以正常功耗模式提供1.8V电源(内核,内存和外设). 停 ...

  6. ChatGPT使用案例,助你快速上手,做事事半功倍

    ChatGPT介绍 首先我们来看一下chat-gpt自己的介绍: ChatGPT的发展历程 2015年,OpenAI成立,致力于研究和开发人工智能技术.在成立初期,OpenAI的创始人之一Elon M ...

  7. 如何从AWS中学习如何使用AmazonSimpleStorageService(S3)进行数据存储

    目录 文章标题:32. <如何从 AWS 中学习如何使用 Amazon Simple Storage Service (S3) 进行数据存储> 背景介绍: 随着数据量的不断增加,数据存储的 ...

  8. 如何刷新 DNS 缓存 (macOS, Linux, Windows)

    如何刷新 DNS 缓存 (macOS, Linux, Windows) Unix Linux Windows 如何刷新 DNS 缓存 (macOS, FreeBSD, RHEL, CentOS, De ...

  9. Codeforces Round #877 (Div. 2) A-E

    A 代码 #include <bits/stdc++.h> using namespace std; using ll = long long; bool solve() { int n; ...

  10. PostgreSQL 性能优化: 等待事件

    等待事件 等待事件是 PostgreSQL 的重要优化工具.当您能查明会话为什么在等待资源以及会话在做什么时,您就能更好地减少瓶颈.您可以使用本节中的信息来查找可能的原因和纠正措施. 目录 等待事件概 ...