【算法】对二分搜索的理解

二分搜索大家都很熟悉,首先我们先来看看基本框架

func binarySearch(nums []int, target int) int {left, right := 0, ...for ... {mid := left + (right-left)/2if nums[mid] == target {...} else if nums[mid] < target {left = ...} else if nums[mid] > target {right = ...}}return ...
}

看完代码之后我们会发现:

  1. 数组得是有序的才能成立
  2. 在存在两个及以上的答案时,只能找出一个,至于下标的情况我觉得可以自定义
  3. 如果数组长度为偶数,初始化时mid在中间偏左的那一格

接下来在实战中看:

寻找一个数

这可以说是最简单的内容

func binarySearch(nums []int, target int) int {left := 0 //right := len(nums) - 1 for left <= right {mid := left + (right - left) / 2 if nums[mid] == target { return mid} else if nums[mid] < target { left = mid + 1 // [mid + 1, right]} else if nums[mid] > target { // 目标值在左半部分,注意right = mid - 1 // [left, mid - 1]}}return -1 // 未找到
}

这里需要注意一点,为何是 for left <= right 而不是 for left < right

我们可以先从最极端的情况入手,假设要寻找的数在最后一个,那么在前一步应该是 left = right - 1, mid = left ,然后 left = mid + 1 = right,在进行循环时,循环就会进不去。

从理论上解释,因为在之前设定值时,数组为闭区间 [left, right] ,所以得保证边界值,也就是说,循环的条件设定和搜索区间设定是相关联的

寻找左侧边界

那么接下来看一下右侧开区间的做法:

func leftBound(nums []int, target int) int {left := 0right := len(nums)for left < right {mid := left + (right - left) / 2if nums[mid] == target {right = mid} else if nums[mid] < target {left = mid + 1 // [mid + 1, right)} else if nums[mid] > target {right = mid // [left, mid)}}return left
}

不难发现,随着区间的修改,在对应条件下的操作也会对应转换。

在这里阐述一点我的个人想法,二分查找的最大特点在于区间设定,而在对应条件下做出的操作有点像递归,基本盘并没有改变

寻找右侧边界

func right_bound(nums []int, target int) int {left, right := 0, len(nums)for left < right {mid := left + (right-left)/2if nums[mid] == target {   left = mid + 1        } else if nums[mid] < target {left = mid + 1} else if nums[mid] > target {right = mid}}return left - 1  
}

这里面的精华在于

if nums[mid] == target {   left = mid + 1 

他并没有直接的收网,而是继续直到最右侧的诞生,这也得益于mid的设置,可以把他看成以left为基准向前进

实战

我们来看力扣的34. 在排序数组中查找元素的第一个和最后一个位置

直接把方法摆上既可以解决

func searchRange(nums []int, target int) []int {left := leftBound(nums, target)right := rightBound(nums, target)return []int{left, right}
}func leftBound(nums []int, target int) int {left, right := 0, len(nums)-1for left <= right {mid := left + (right - left) / 2if nums[mid] < target {left = mid + 1} else if nums[mid] > target {right = mid - 1} else if nums[mid] == target {// 别返回,锁定左侧边界right = mid - 1}}// 判断 target 是否存在于 nums 中if left < 0 || left >= len(nums) {return -1}// 判断一下 nums[left] 是不是 targetif nums[left] == target {return left}return -1
}func rightBound(nums []int, target int) int {left, right := 0, len(nums)-1for left <= right {mid := left + (right - left) / 2if nums[mid] < target {left = mid + 1} else if nums[mid] > target {right = mid - 1} else if nums[mid] == target {// 别返回,锁定右侧边界left = mid + 1}}// 判断 target 是否存在于 nums 中// if left - 1 < 0 || left - 1 >= len(nums) {//     return -1// }if right < 0 || right >= len(nums) {return -1}if nums[right] == target {return right}return -1
}

当然也有另外一种解法,力扣显示这种时间复杂度更低
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/201368.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

圈子社交系统:打破时间与空间的限制。APP小程序H5三端源码交付,支持二开!

在现代社会&#xff0c;社交已成为人们生活中不可或缺的一部分。然而&#xff0c;传统的社交方式往往受制于时间和空间的限制&#xff0c;使得人们难以充分发挥社交的潜力。为了解决这一问题&#xff0c;圈子社交系统应运而生。 圈子社交系统通过技术手段打破时间与空间的限制&…

Linux环境搭建SVN服务器并结合内网穿透实现远程访问

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;网络奇遇记、Cpolar杂谈 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. Ubuntu安装SVN服务二. 修改配置文件2.1 修改svnserve.conf文件2.2 修改pass…

【Linux】cp 命令使用

cp 命令 cp&#xff08;英文全拼&#xff1a;copy file&#xff09;命令主要用于复制文件或目录。 著者 由Torbjorn Granlund、David MacKenzie和Jim Meyering撰写。 语法 cp [选项]... [-T] 源文件 目标文件或&#xff1a;cp [选项]... 源文件... 目录或&#xff1a;cp [选…

synchronized关键字-监视器锁(monitor lock)

这就是我们上一篇中代码提到的加锁的主要方式,本质上是调用系统api进行加锁,系统api本质是靠cpu特定指令加锁. synchronize的特性 互斥性 synchronized会起到互斥效果,某个线程执行到某个对象的synchronized中时,,其它线程如果也执行到同一个对象synchronized就会阻塞等待(锁…

Python实现FA萤火虫优化算法优化卷积神经网络回归模型(CNN回归算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 萤火虫算法&#xff08;Fire-fly algorithm&#xff0c;FA&#xff09;由剑桥大学Yang于2009年提出 , …

小航助学题库白名单竞赛考级蓝桥杯等考scratch(8级)(含题库教师学生账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09; 需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;

Java核心知识点整理大全26-笔记

目录 27. Storm 7.1.1. 概念 27.1.1. 集群架构 27.1.1.1. Nimbus&#xff08;master-代码分发给 Supervisor&#xff09; 27.1.1.2. Supervisor&#xff08;slave-管理 Worker 进程的启动和终止&#xff09; 27.1.1.3. Worker&#xff08;具体处理组件逻辑的进程&#xff…

分包(微信小程序)

首先&#xff0c;微信小程序中使用分包是为了减少首屏的请求&#xff0c;因为微信小程序会默认下载主包内的内容并展示到页面上&#xff0c;但是随着业务量的增加&#xff0c;代码量也会越来越大。会导致我们启动小程序的时候首页加载速度过慢的这个问题。这时我们就可以采用分…

解决(error) ERR Errors trying to SHUTDOWN. Check logs.问题~

该问题出现在我在使用shutdown关闭redis服务器时&#xff0c;出现该问题的原因是由于配置文件的日志文件位置未配置或者缺少日志文件 我自己出现该问题是因为缺少日志文件&#xff0c;解决步骤如下所示&#xff1a; 第一步&#xff1a;在该目录下使用touch命令创建日志文件 第…

【工具与中间件】快速构建飞书群聊机器人

文章目录 0. 前言1. 无痛入门1.1 飞书创建群聊机器人1.2 Webhook 请求示例1.3 设置安全策略 2. 实战3. 总结3.1 使用体验3.2 深入使用建议 先进团队用飞书&#xff0c;先进飞书群聊有...... 0. 前言 科技蓬勃发展的今天&#xff0c;我们可以轻松拥有属于自己/团队的机器人。日…

Ubuntu18.04 本地安装CVAT标注工具

写在前面&#xff1a; 1、如果直接clone最新版本的cvat&#xff0c;python版本最好安装3.8的&#xff0c;因为其中部分代码的语法只有高版本的python才可以支持。 2、安装完成以后本地登陆可能出现"cannot connect to cvat server"的错误&#xff0c;可以从Cannot …

制作麒麟oem镜像之通过识别终端品牌与BIOS安装不同内容

原文链接&#xff1a;麒麟oem镜像之识别终端品牌与BIOS安装不同内容 **hello&#xff0c;大家好啊&#xff01;**在个性化和定制化日益成为趋势的今天&#xff0c;操作系统的定制化安装也变得越来越重要。特别是对于企业用户来说&#xff0c;能够根据不同的硬件配置和需求&…

项目实战之RabbitMQ重试机制进行消息补偿通知

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;啥技术都喜欢捣鼓捣鼓&#xff0c;喜欢分享技术、经验、生活。 &#x1f60e;人生感悟&#xff1a;尝尽人生百味&#xff0c;方知世间冷暖。 文章目录 &#x1f31f;架构图&#x…

Python Tkinter库入门与基础

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Tkinter是Python标准库中内置的图形用户界面&#xff08;GUI&#xff09;工具包&#xff0c;提供了创建窗口、按钮、文本框等GUI元素的功能。本文将介绍Tkinter的基础知识&#xff0c;帮助大家快速入门。 安装与…

低成本物联网安全芯片ACL16_S 系列,可应用物联网认证、 SIM、防抄板和设备认证等产品上

ACL16_S 芯片是针对物联网认证、 SIM、防抄板和设备认证需求推出的高安全芯片。芯片采用 32 位 ARMCortex™-M0 系列内核&#xff0c;片内集成多种安全密码模块&#xff0c;包括 RSA/ECC DES/TDES、 SHA-1/-256、 AES-128/-192/-256 等国际安全算法&#xff0c;支持真随机数发…

岳阳楼3D模型纹理贴图

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 岳阳楼&#xff0c;位于湖南省岳阳市岳阳楼区洞庭北路&#xff0c;地…

Vcenter 6.7 VCSA证书过期问题处理

1. 故障现象 2022年10月25日&#xff0c;登陆VC报错。 按照报错信息&#xff0c;结合官方文档&#xff0c;判断为STS证书过期导致。 vCenter Server Appliance (VCSA) 6.5.x, 6.7.x or vCenter Server 7.0.x 在/var/log/vmware/vpxd-svcs/vpxd-svcs.log看到类似报错: ERRO…

为什么程序员会讨厌PHP编程语言?

闲来无事&#xff0c;逛了某乎看见一篇关于PHP编程的学习指南&#xff0c;深受启发。我们都知道PHP是一种流行的爬虫语言&#xff0c;尤其在Web开发方面。太有很多有点&#xff0c;例如简单易学、支持的成许多等。但是PHP也会存在一些缺点&#xff0c;如代码可读性差&#xff0…

Windows下Linkis1.5DSS1.1.2本地调试

1 Linkis: 参考&#xff1a; 单机部署 | Apache Linkis技术分享 | 在本地开发调试Linkis的源码 (qq.com)DataSphere Studio1.0本地调试开发指南 - 掘金 (juejin.cn) 1.1 后端编译 参考【后端编译 | Apache Linkis】】 修改linkis模块下pom.xml,将mysql.connetor.scope修改…

go-fastfds部署心得

我是windows系统安装 Docker Desktop部署 docker run --name go-fastdfs&#xff08;任意的一个名称&#xff09; --privilegedtrue -t -p 3666:8080 -v /data/fasttdfs_data:/data -e GO_FASTDFS_DIR/data sjqzhang/go-fastdfs:lastest docker run&#xff1a;该命令用于运…