【Python】算法刷题之二分查找

2023-10-30

二分查找的秘密

二分查找法,其实也叫“折半查找”,是一种效率较高的查找方法。同时它也告诉了我们使用的条件,首先线性表需要是有序的,并且不能有重复元素,这就是使用它的前提条件。看到可能会觉得好像很容易呀,虽然我们判断是否使用二分查找不难,但是我们在实际用它的使用却会感到麻烦不小,为什么呢?

因为我们需要考虑边界条件,由于我们很多时候对区间的定义没有想清楚,区间的定义就是不变量。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则。

模版写法

前言: 模版不一定就是照抄,理解模版基本就能理解方法思路啦

我们能常见到的有什么区间左闭右闭法,区间左闭右开法,这里我们不强调使用什么方法,总的都是一个原则,那就是能够保证在二分查找过程中,保持不变量;自己比较习惯于用左闭右闭法,也就是[left, right]

区间的定义这就决定了二分法的代码应该如何写,因为定义target在[left, right]区间,所以有如下两点:
while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1

如果用左闭右开法的话也是类似的,只不过left<right,因为left == right在区间[left, right)是没有意义的,所以大家注意怎么去对区间进行定义就可以啦

代码如下:

class Solution:
    def search(self, nums: List[int], target: int) -> int:
    	#1.定义区间变量left, right
        left, right = 0, len(nums) - 1
        #保证循环不变量,每一次的边界处理都是根据区间操作的
        while left <= right:
        	#折半取中间值middle
            middle = (left + right) // 2
            #如果中间值小于了目标值,则取右半区,由于middle绝不会等于target,所有left等于middle+1
            if nums[middle] < target:
                left = middle + 1
            #如果大于的话,取左半区,同样因为右半区值有意义,所以需要middle-1
            elif nums[middle] > target:
                right = middle - 1
            #如果等于,则返回middle
            else:
                return middle
        return -1

开始做题

69.x的平方

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。 由于返回类型是整数,结果只保留整数部分 ,小数部分将被舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。

示例 1: 输入:x = 4 输出:2

示例 2: 输入:x = 8 输出:2
解释:8 的算术平方根是 2.82842…, 由于返回类型是整数,小数

代码如下:

class Solution:
    def mySqrt(self, x: int) -> int:
        left, right = 0, x
        ans = -1
        while left <= right:
            middle = (right - left) // 2 + left
            if middle * middle <= x:
                ans = middle
                left = middle + 1
            else:
                right = middle - 1
        return ans

34.在排序数组中查找元素的第一个和最后一个位置

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2:
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]

代码如下:

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        # 两次二分查找
        # 取起始下标
        left, right = 0, len(nums) - 1
        while left < right:
            mid = (left + right) // 2
            if nums[mid] >= target:
                right = mid
            else:
                left = mid + 1
        # 数组不存在或者目标值不在数组中
        if not nums or nums[left] != target:
            return [-1, -1]
        # 取结束下标
        a, b = left, len(nums) - 1
        while a < b:
            mid = (a + b + 1) // 2
            if nums[mid] <= target:
                a = mid
            else:
                b = mid - 1
        return [left, a]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Python】算法刷题之二分查找 的相关文章

随机推荐

  • 无人系统群体智能及其研究进展

    来源 无人机 作者 周兴社 武文亮 西北工业大学 计算机学院 陕西 西安 710129 摘 要 群体智能是人工智能的重要发展方向之一 无人系统群体智能作为人工群体智能的主要形态之一 在许多军用和民用领域都具有广阔且重要的应用前景 同时在基础
  • 服务网格实施周期缩短 50%,丽迅物流基于阿里云 ACK 和 ASM 的云原生应用管理实践

    作者 王夕宁 刘强 华相 公司介绍 丽迅物流是百丽旗下专注于时尚产业 为企业提供专业物流及供应链解决方案的服务商 其产品服务主要包括城市落地配 仓配一体 干线运输及定制化解决方案 通过自研智能化物流管理平台 全面助力企业合作集约化发展 目前
  • Ext_面板_Ext.Panel .

    javascript view plain copy print Ext Panel主要配置表 animCollapse Boolean 设置面板折叠展开是否显示动画 Ext Fx可用默认true 否则false applyTo Mixed
  • orm框架有哪些_Java架构—Spring 核心框架体系结构

    很多人都在用spring开发java项目 但是配置maven依赖的时候并不能明确要配置哪些spring的jar 经常是胡乱添加一堆 编译或运行报错就继续配置jar依赖 导致spring依赖混乱 甚至下一次创建相同类型的工程时也不知道要配置哪
  • nodeJS ejs模板引擎 片段视图+视图助手

    Express 的视图系统还支持片段视图 partials 它就是一个页面的片段 通常是重复的 内容 用于迭代显示 通过它你可以将相对独立的页面块分割出去 而且可以避免显式地使 用 for 循环 让我们看一个例子 在 app js 中新增以
  • WPF Window窗体属性

    XAML的三个顶级元素 Window UserControl 用户控件 Page把窗体以网页形式展现 而一个XAML页面里只能有一个顶级元素 顶级元素只能有一个子元素 在窗体里面设置窗体属性
  • 数值计算基础(二)线性方程解法篇

    概要 介绍了1 直接法 高斯消去法 列主元消去法 LU分解 平方分解 平方分解改进 追赶法 2 迭代法 雅各比迭代 高斯赛德尔迭代 SOR迭代 求解方程3 迭代法收敛性 1 高斯消去法 用途 解方程 核心 将矩阵直接化为上三角矩阵 注意系数
  • 30秒学会 —— 《获取验证码基本操作》

    前期回顾 懒人必备 时间神器 moment 0 活在风浪里的博客 CSDN博客亲测好用 及其好使的插件 开发懒人必整 就算是自己可以写 一大堆代码 真的要写吗 https blog csdn net m0 57904695 article
  • 黑豆泡醋

    实践 黑豆泡醋真的很有作用 感谢JRs热情捧场 再写具体些 由 后入金正恩 发表在 虎扑篮球 步行街 http bbs hupu com bxj 这瓶黑豆泡醋都有半年了 是半年前奶奶泡的 一直懒得吃 直到最近才吃 谁知道功效真的不错 LZ现
  • qt connect连接失效的情况:selectionModel

    connect ui treeView gt selectionModel QItemSelectionModel currentRowChanged this DataSetQueryWidget SlotTreeViewClicked
  • 数字电路时序分析基础

    目录 CMOS时序模型基础 线性延时模型 时序约束 输入电容 NLDM与CCS NLDM CCS STA基础 CMOS时序模型基础 大多数简化的时序模型基于以下公式 D e l a
  • MySQL - orderBy 排序规则

    我们平时使用数据库按字段排序的时候 必定使用ORDER BY来操作数据库数据 但是order by到底以什么规则排序的 嗯 order by 后面 跟上 你需要排序的字段 默认 是升序 排列 sql语句中 order by 排序原则 ORD
  • parent.relativePath' points at wrong local POM

    这个错误通常是下载了子项目 没有把父项目下载下来 子项目要依赖父项目的pom The relative path of the parent pom xml file within the check out If not specifie
  • #BDA#笔记#先导课:数据分析的定义和应用

    即席查询 即席查询 Ad Hoc 是用户根据自己的需求 灵活的选择查询条件 系统能够根据用户的选择生成相应的统计报表 即席查询与普通应用查询最大的不同是普通的应用查询是定制开发的 而即席查询是由用户自定义查询条件的 GMV Gross Me
  • Unity 2d碰撞检测

    碰撞检测 Collider2d 射线检测函数 Raycast 与 Cast 函数 Overlap 检测函数 参数 PhysicsScene2D 类检测函数 Physics2D 类检测函数 MonoBehaviour 类碰撞检测函数 Coll
  • Spring Security实现登录

    前言 Spring Security是Spring框架下的一个用于身份验证和授权的框架 它可以帮忙管理web应用中的用户认证 授权以及安全性问题 本文将介绍如何使用Spring Security实现用户登录功能 本文主要包括以下内容 环境准
  • Java 之路 (六) -- 访问权限控制(Package、Public、protected、friendly、private)

    这一章内容比较少 也比较基础 不多废话 下面开始这一章的学习吧 学习内容 包 package 访问权限 public protected 默认 private 1 Package 1 原因 为了更好的组织类 Java 提供了包机制 用来区别
  • python如何显示html文档

    Python提供了多种库可以用来显示HTML文档 其中比较常用的是webbrowser和IPython display模块 使用webbrowser模块打开HTML文件 import webbrowser webbrowser open e
  • 【python爬虫】6.爬虫实操(带参数请求数据)

    文章目录 前言 项目 狂热粉丝 分析过程 什么是带参数请求数据 如何带参数请求数据 代码实现 被隐藏的歌曲清单 什么是Request Headers 如何添加Request Headers 复习 前言 先来复习一下上一关的主要知识吧 先热个
  • 【Python】算法刷题之二分查找

    二分查找 二分查找的秘密 模版写法 开始做题 69 x的平方 34 在排序数组中查找元素的第一个和最后一个位置 二分查找的秘密 二分查找法 其实也叫 折半查找 是一种效率较高的查找方法 同时它也告诉了我们使用的条件 首先线性表需要是有序的