二分查找

介绍

二分查找是一种在有序数组中查找某一特定元素的搜索算法。这种算法了解了会觉得很简单,但做题就非常容易出错,这篇文章是我整理的做题总结,如果你做题也迷迷糊糊 那可能会对你有帮助!

工作原理

你的目标是以最少的次数猜到这个数字。你每次猜测后,我会说小了、大了或对了。

方式有两种:

  1. 假设你从1开始依次往上猜,那目标值是57就一共猜了57次。
  2. 使用更聪明的方式,猜测过程会是这样。

小了,但排除了一半的数字!至此,你知道1~50都小了。接下来,你猜75。

大了,那余下的数字又排除了一半!使用二分查找时,你猜测的是中间的数字,从而每次都将余下的数字排除一半。接下来,你猜63(50和75中间的数字)。

这就是二分查找,你学习了第一种算法!恭喜你~

例子

ini 复制代码
(力扣35题)
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。

示例1:
输入: nums = [1,3,5,6,7,8,10,12], target = 5
输出: 2
完整代码:
var searchInsert = function(nums, target) {
    let left = 0   //设置查找区间
    let right = nums.length - 1
    let ans = nums.length
    while (left <= right) {
        let mid = Math.floor((left + right) / 2) //向上或向下取整都可以
        if( target <= nums[mid] ){
            ans = mid
            right = mid -1
        }else{
            left = mid + 1
        }
    }
    return ans
}

执行过程

设置左右边界,求出mid位置,5<target right需要移动

再次求出mid后,5并不小于target,left需要移动

再次求出mid后,5<=target,left没有重合依然在循环体里面 所以继续移动right

left和right重合这是循环体里的最后一次执行,返回mid

区间问题

上面的例子属于左闭有闭的区间

网上看了好多二分查找的模版如(左闭右开、左开右闭、左闭右闭、左开右开)。我个人觉得任何一种模版都不是万能的,逐个研究没有意义,选个一自己思考起来最顺手的就好,解决只能回到题目的场景去思考。

另外左右的边界地位是相等的 我暂时也不想到为什么要让其中一方取不到(狗头)

注意事项

在写二分查找时我们需要清楚

  • 循环可以继续的条件是什么
  • mid位置的值是否可能是问题的答案
  • 下一轮搜索想左还是向右
相关推荐
老鼠只爱大米2 分钟前
LeetCode经典算法面试题 #215:数组中的第K个最大元素(快速选择、堆排序、计数排序等多种实现方案详解)
算法·leetcode·堆排序·快速选择·topk·数组中的第k个最大元素
2301_816651229 分钟前
C++中的享元模式变体
开发语言·c++·算法
逆境不可逃11 分钟前
LeetCode 热题 100 之 35. 搜索插入位置 74. 搜索二维矩阵 34. 在排序数组中查找元素的第一个和最后一个位置
数据结构·算法·leetcode
m0_5832031312 分钟前
C++中的访问者模式变体
开发语言·c++·算法
浅念-19 分钟前
C ++ 智能指针
c语言·开发语言·数据结构·c++·经验分享·笔记·算法
不染尘.20 分钟前
最小生成树算法
开发语言·数据结构·c++·算法·图论
Klong.k33 分钟前
判断是不是素数题目
数据结构·算法
QQsuccess34 分钟前
AI全体系保姆级详讲——第一部分:了解AI基本定义
人工智能·算法
_日拱一卒37 分钟前
LeetCode:移动零
算法·leetcode·职场和发展
A923A1 小时前
【洛谷刷题 | 第四天】
算法·前缀和·贪心·洛谷·差分