【优选算法 二分查找】二分查找算法入门详解:二分查找小专题

     

 


  x 的平方根


     题目解析     


    算法原理     


    解法一: 暴力解法    


如果要求一个数(x)的平方根,可以从 0 往后枚举,直到有一个数(a),a^2<=x,(a+1)^2>x,a即为所求;


    解法二:二分查找     


    分析二段性     


因为暴力枚举的数字从1开始递增,所以枚举的数是有序的,并且能以 a 为边界点,把枚举的数组分成两个部分 :


因为这道题分 a^2<=x,a^2>x 两种情况,而不是分成三种情况,所以使用不朴素的二分查找;

left 初始化为1,right 的初始化需要商榷,所以以 mid 的值对应的 a^2 和 x 的大小关系进行讨论 :

  • 1.  a^2 <= x

  •  2.  a^2 > x


    处理细节问题    

根据范围,我们可以发现 x 是可以小于1的,如果当 x=0.5之类的小数,那么开根号得到的数的整数部分一定是0,所以当 x<1,直接返回0即可;所以 left 初始化为1


    编写代码    




 搜索插入位置


     题目解析    


    算法原理     


     解法:二分查找   


    查找二段性    


通过下面的例子可以发现,插入的位置要么是第一个大于 target 的数的下标,要么是 target 大于数组中所有元素,而被插入到末尾:

所以插入 target 的位置特点是第一个大于等于 target 的元素下标,这个下标即为返回值,所以有如下二段性:


    left 和 right 的更新策略    


分析 mid 落在上面两个区间时,left 和 right 的更新策略 : 

  • 1.mid >= target

  • 2.mid < target

    编写代码    



 山脉数组的峰顶索引 


      题目解析     


    算法原理    


 如果要找峰顶元素的下标,那么第一个元素和最后一个元素其实是不需要考虑的;


    解法一:暴力枚举    


定义一个指针,从起始位置开始往后扫描,当扫描到一个元素的值大于后面一个元素的值,就返回这个元素的下标,时间复杂度为O(N);


    解法二:二分查找    


     分析二段性     


 我们发现,哪怕这个数组并不是有序的,依旧可以使用二分查找,就是因为数组具有二段性;


     left 和 right 的更新策略    


分析 mid 落在上面两个区间时,left 和 right 的更新策略 :

  • 1. arr[mid] > arr[mid-1]


  • 2. arr[mid] < arr[mid-1]

     编写代码    



寻找峰值


    题目解析     

    算法原理    


  • 如果起始位置是呈现下降趋势的,就直接返回起始位置下标0即可,因为nums[-1]为负无穷;


  •  如果刚开始往后遍历,一直是上升,直到峰值后下降,返回峰值下标:


  • 当遍历完所有数组,都是呈上升趋势,返回最后一个元素下标即可,因为nums[length]为无穷小


    解法一:暴力枚举    


定义一个指针直接往后扫描,根据上面的三种情况作出相应的处理即可;时间复杂度是考虑最坏的情况,如第三种情况,所以为O(N)


    解法二:优化暴力解法,二分查找    


     分析二段性     


 我们分析数组任意区间相邻两个点的情况:

  • 1.  nums[i] > nums[i+1] ,在[0,i] 区间一定存在至少一个峰值,接下来可以去 [0,i] 区间找: 


  • 2.  nums[i] < nums[i+1],在 [i+1,length-1] 区间至少存在一个峰值,所以可以去这个区间找:

所以根据 nums[i] 与 nums[i+1] 的关系,把数组分成了两部分,去其中一个部分查找结果;

刚刚在山峰数组中找索引,还算不上严格的无序;这道题是严格的无序,但是依旧能使用二分查找解决,说明二段性是决定一个题能否使用二分查找的必要条件;


     left 和 right 的更新策略    


 根据 arr[mid] 和 arr[mid+1] 的关系,更新left 和right;

  • 1.  arr[mid] > arr[mid+1] ,在[0,mid] 区间一定存在至少一个峰值:


  • 2. arr[mid] < arr[mid+1],在 [i+1,length-1] 区间至少存在一个峰值:

    编写代码     


     暴力枚举     


     二分查找     


 寻找旋转排序数组中的最小值


     题目描述    


    算法原理    


经过旋转的数组有什么特性呢?


 因为数组元素是互不相同的,所以折线图又可以分成两部分:

左边部分严格在nums的分界线上面,右边部分严格在nums分界线下面,并且两个折线部分都是递增的;


    解法一:暴力枚举    


从前往后扫描数组,直到找到最小值;时间复杂度O(N);暴力解法慢就慢在没有利用旋转数组能分成两个递增折线,且左边严格高于右边的特性; 


    解法二:二分查找    


    分析二段性    


如果把问题抽象成折现图,那么就会发现这个数组有明显的二段性,数组的两个部分被分界线严格划分; 对于AC,nums[i] > nums[length-1];对于DE,nums<=nums[length-1];

注意:本题的特殊之处,是拿中间元素的值和末尾元素的值的大小关系,来分成两个区间 


所以要找最小值,我们只需要找到下标分割线所在的位置,即是最小值下标位置,所以就是查找右边区域的左端点


    left 和 right 的更新策略    


 分析 mid 落在上面两个区间时,left 和 right 的更新策略 :

注意,这个数组是经过有序递增数组旋转得到的数组,这就避免了很多边界情况的讨论,旋转数组的值分布一定是分成两个递增折线,并且左边折线严格都大于右边;

  •     1. AC:nums[mid] > nums[length-1]    


  •     2. DF:nums[mid] <= nums[length-1]    

上面是以末尾元素为参照物,我们可以选起始元素为参照点吗?

我们发现,AC区间是严格大于nums[0] 的,CD区间也是严格小于 nums[0] 的,也具有二段性;


    编写代码    


 


0~n-1中缺失的数字


   题目描述   



    算法原理    


    解法一:哈希表    


如果是n个数字,就建 n+1个桶的哈希表,遍历原始数组并且填入哈希表,最后找出 val=0 的key即可;时间复杂度为 O(N),但是还要利用O(N)的空间复杂度


    解法二:直接遍历    


从前往后直接遍历,时间复杂度为 O(N);


    解法三  :位运算     


异或 ^ ,把缺失元素的数组,和完整数组的每一个元素进行异或操作:

 


异或有一个特性,就是相同元素相互抵消,最终异或结果就是缺失的数;

时间复杂度为 O(N)


       解法四:数学方法(高斯 / 等差数列求和公式)    


因为数组是一个等差升序数组,就是一个等差数列,把完整的数组通过等差数列求和公式求出,再依次减去缺失数字的数组,即可得到缺失的元素;时间复杂度为 O(N)


     解法五:二分查找      


    分析二段性    


我们把缺失元素的数组下标标注出来,帮助我们发现二段性: 

此时,我们发现,数组可以分成两个区域,下标和元素一 一对应是一个区域,不是一 一对应,则是类外一个区域,因此,这个数组就有二段性;


    left 和 right 的更新策略    


如果下标和元素对应,left=mid+1,不能对应则 right = mid; 


    编写代码    


 

可以把两种特殊的情况合并成一种:


     

 

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

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

相关文章

理工男创业方案:一款智能AI久坐提醒器产品的技术实现方案

起身提醒器技术实现方案 随着现代工作方式的改变&#xff0c;越来越多的上班族长时间坐在电脑前&#xff0c;缺乏足够的活动&#xff0c;容易导致各种健康问题&#xff0c;如脊椎病、眼睛疲劳、肌肉酸痛等。因此&#xff0c;设计一款智能起身提醒器&#xff0c;以帮助用户改善…

查询产品所涉及的表有(product、product_admin_mapping)

文章目录 1、ProductController2、AdminCommonService3、ProductApiService4、ProductCommonService5、ProductSqlService1. 完整SQL分析可选部分&#xff08;条件筛选&#xff09;&#xff1a; 2. 涉及的表3. 总结4. 功能概述 查询指定管理员下所有产品所涉及的表&#xff1f;…

错误:pip报No module named ‘pip‘错怎么处理

有时候在执行pip更新失败后&#xff0c;再次执行pip命令时会提示ModuleNotFoundError: No module named pip’错误&#xff0c;导致pip命令无法使用 现象 重新打开一个cmd命令窗口&#xff0c;选择使用管理员权限打开&#xff1a;可以直接右键或是点击右侧功能&#xff0c;以…

SSM虾米音乐项目2--分页查询

1.分页查询的底层逻辑 首先根据用户输入的流派&#xff0c;进行模糊查询根据查询的数据进行分页需要前端用户提供pageNo(当前页数)和pageSize(每页的数据量)并且要从后端计算count(总数据量)和totalPage(总页数)&#xff0c;以及startNum(每页开始的记录)从而将对应的页面数据…

npm, yarn, pnpm之间的区别

前言 在现代化的开发中&#xff0c;一个人可能同时开发多个项目&#xff0c;安装的项目越来越多&#xff0c;所随之安装的依赖包也越来越臃肿&#xff0c;而且有时候所安装的速度也很慢&#xff0c;甚至会安装失败。 因此我们就需要去了解一下&#xff0c;我们的包管理器&#…

Idea Spring Initializr没有 Java 8选项解决办法

问题描述 在使用IDEA中的Spring Initializr创建新项目时&#xff0c;Java 版本近可选择Java17,21 。不能选择Java8;SpringBoot 版本也只有 3.x 问题原因 Spring 官方&#xff08; https://start.spring.io/&#xff09;不再提供旧版本的初始化配置 解决方案 方案 1 使用阿里…

使用 Vue 和 Canvas-Confetti 实现烟花动画特效

在开发中&#xff0c;为用户提供具有视觉冲击力的反馈是一种提升用户体验的好方法。今天&#xff0c;我们将结合 Vue 框架、canvas-confetti 和 Lottie 动画&#xff0c;创建一个动态对话框动画&#xff0c;其中包含炫酷的烟花特效。 效果图&#xff1a; 效果简介 当用户触发…

IDEA的service窗口中启动类是灰色且容易消失

大家在学习Spring Cloud的过程中,随着项目的深入,会分出很多个微服务,当我们的服务数量大于等于三个的时候,IDEA会给我们的服务整理起来,类似于这样 但是当我们的微服务数量达到5个以上的时候,再启动服务的时候,服务的启动类就会变成灰色,而且还容易丢失 解决方法 我们按住…

Vue智慧商城项目

创建项目 vue组件库 — vant-ui&#xff08;常用于移动端&#xff09; Vant 2 - 轻量、可靠的移动端组件库 安装vant npm i vantlatest-v2 -S 引入组件 按需导入和全部导入 全部导入 整个组件库的所有组件都导进来&#xff0c;缺点是增加了代码包体积 main.js import…

特朗普画像

任务内容 Description 特朗普当选了&#xff0c;网上流传着很多段子&#xff0c;也出了特朗普的头像。有人说&#xff0c;特朗普 的头像像一团云。所以今年马云去了美国和特朗普谈中美企业的发展。那么你能帮 忙打印出特朗普的头像吗&#xff1f; 抽象派认为&#xff0c;特朗普…

【NIPS2024】Unique3D:从单张图像高效生成高质量的3D网格

背景&#xff08;现有方法的不足&#xff09;&#xff1a; 基于Score Distillation Sampling &#xff08;SDS&#xff09;的方法&#xff1a;从大型二维扩散模型中提取3D知识&#xff0c;生成多样化的3D结果&#xff0c;但存在每个案例长时间优化问题/不一致问题。 目前通过微…

cocotb value cocotb—基础语法对照篇

cocotb—基础语法对照篇 import cocotb from cocotb.triggers import Timer from adder_model import adder_model from cocotb.clock import Clock from cocotb.triggers import RisingEdge import randomcocotb.test() async def adder_basic_test(dut):"""Te…

万物可爬(以爬取浏览器井盖图片和豆瓣电影名字为例)

我们以爬取 井盖图片 这个链接中的图片为例&#xff1a; 点击F12 并选中其中一张图片 &#xff0c;得到它的信息。具体如下&#xff1a;我们可以编写对应的正则表达式&#xff1a; <img[^>]*src"(.*?)"[^>]*alt"井盖图片 的图像结果"[^>]*&g…

MySQL-DDL之数据库操作

文章目录 一. 创建数据库1. 直接创建数据库&#xff0c;如果存在则报错2. 如果数据库不存在则创建3. 创建数据库时设置字符集4. 栗子 二. 查看数据库1. 查看数据库 三. 删除数据库1. 删除数据库 四. 使用数据库1. 使用数据库2. 查看正在使用的数据库 数据定义语言&#xff1a;简…

3D 生成重建020-Gaussian Grouping在场景中分割并编辑一切

3D 生成重建020-Gaussian Grouping在场景中分割并编辑一切 文章目录 0 论文工作1 方法2 实验结果 0 论文工作 最近提出的高斯Splatting方法实现了高质量的实时三维场景新视角合成。然而&#xff0c;它仅仅关注外观和几何建模&#xff0c;缺乏细粒度的物体级场景理解。为了解决…

Unity 使用LineRenderer制作模拟2d绳子

效果展示&#xff1a; 实现如下&#xff1a; 首先&#xff0c;直接上代码&#xff1a; using System.Collections; using System.Collections.Generic; using UnityEngine;public class LineFourRender : MonoBehaviour {public Transform StartNode;public Transform MidNod…

Linux-ADC驱动实验

上一章我们讲解了如何给 ICM20608 编写 IIO 驱动&#xff0c;ICM20608 本质就是 ADC&#xff0c;因此纯粹的 ADC 驱动也是 IIO 驱动框架的。本章我们就来学习一下如何使用 I.MX6ULL 内部的 ADC&#xff0c;并且在学习巩固一下 IIO 驱动。 ADC 驱动源码简析 设备树下的 ADC 节点…

Rigol DP711自动控制--SCPI命令

通过串口的SCPI命令来控制通道输入输出 也可以用UltraSigma UI来发送SCPI 物理连接&#xff1a; Pin2_2, Pin3_3, Pin5_5 串口命令控制&#xff1a; 命令&#xff1a;9600&#xff0c; 8bit, None SCPI CMD(Standard Commands for Programmable Instruments) OUTPut CH1, On…

Unity类银河战士恶魔城学习总结(P167 Blackhole additional vfx 黑洞技能额外特效)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址&#xff1a;https://www.udemy.com/course/2d-rpg-alexdev/ 为黑洞技能增加了额外的特效 BlackHole_Skill_Controller.cs 功能概要&#xff1a; 1. 黑洞技能的初始化与配置 SetupBlackhole: 设置黑…

小红薯x-s算法最新补环境教程12-06更新(下)

在上一篇文章中已经讲了如何去定位x-s生成的位置&#xff0c;本篇文章就直接开始撸代码吧 如果没看过的话可以看&#xff1a;小红薯最新x-s算法分析12-06&#xff08;x-s 56&#xff09;&#xff08;上&#xff09;-CSDN博客 1、获取加密块代码 首先来到参数生成的位置&…