二分查找——OJ题(一)

news2025/1/18 14:03:29

在这里插入图片描述


📘北尘_:个人主页

🌎个人专栏:《Linux操作系统》《经典算法试题 》《C++》 《数据结构与算法》

☀️走在路上,不忘来时的初心

文章目录

  • 一、二分查找
    • 1、题目讲解
    • 2、算法原理
    • 3、代码实现
  • 二、在排序数组中查找元素的第一个和最后一个位置
    • 1、题目讲解
    • 2、算法原理
    • 3、代码实现
  • 三、X的平方根
    • 1、题目讲解
    • 2、算法原理
    • 3、代码实现
  • 四、搜索插入位置
    • 1、题目讲解
    • 2、算法原理
    • 3、代码实现


一、二分查找

1、题目讲解

在这里插入图片描述

2、算法原理

a. 定义 left , right 指针,分别指向数组的左右区间。
b. 找到待查找区间的中间点 mid ,找到之后分三种情况讨论:
i. arr[mid] == target 说明正好找到,返回 mid 的值;
ii. arr[mid] > target 说明 [mid, right] 这段区间都是⼤于 target 的,因此舍去右边区间,在左边 [left, mid -1] 的区间继续查找,即让 right = mid - 1 ,然后重复 2 过程;
iii. arr[mid] < target 说明 [left, mid] 这段区间的值都是⼩于 target 的,因此舍去左边区间,在右边 [mid + 1, right] 区间继续查找,即让 left = mid + 1 ,然后重复 2 过程;
c. 当 left 与 right 错开时,说明整个区间都没有这个数,返回 -1 。

3、代码实现

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left=0,right=nums.size()-1;
        while(left<=right)
        {
            int mid=left+(right-left)/2;
            if(nums[mid]<target) left=mid+1;
            else if(nums[mid]>target )right=mid-1;
            else return mid;
        }
       return -1;
    }
};

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

1、题目讲解

在这里插入图片描述

2、算法原理

⽤的还是⼆分思想,就是根据数据的性质,在某种判断条件下将区间⼀分为⼆,然后舍去其中⼀个区间,然后再另⼀个区间内查找;
⽅便叙述,⽤ x 表⽰该元素, resLeft 表⽰左边界, resRight 表⽰右边界。
寻找左边界思路:
• 寻找左边界:
◦ 我们注意到以左边界划分的两个区间的特点:
▪ 左边区间 [left, resLeft - 1] 都是⼩于 x 的;
▪ 右边区间(包括左边界) [resLeft, right] 都是⼤于等于 x 的;
• 因此,关于 mid 的落点,我们可以分为下⾯两种情况:
◦ 当我们的 mid 落在 [left, resLeft - 1] 区间的时候,也就是 arr[mid] < target 。说明 [left, mid] 都是可以舍去的,此时更新 left 到 mid + 1 的位置,
继续在 [mid + 1, right] 上寻找左边界;
◦ 当 mid 落在 [resLeft, right] 的区间的时候,也就是 arr[mid] >= target 。
说明 [mid + 1, right] (因为 mid 可能是最终结果,不能舍去)是可以舍去的,此时
更新 right 到 mid 的位置,继续在 [left, mid] 上寻找左边界;
• 由此,就可以通过⼆分,来快速寻找左边界;
注意:这⾥找中间元素需要向下取整。
因为后续移动左右指针的时候:
• 左指针: left = mid + 1 ,是会向后移动的,因此区间是会缩⼩的;
• 右指针: right = mid ,可能会原地踏步(⽐如:如果向上取整的话,如果剩下 1,2 两个元
素, left == 1 , right == 2 , mid == 2 。更新区间之后, left,right,mid 的
值没有改变,就会陷⼊死循环)。
因此⼀定要注意,当 right = mid 的时候,要向下取整。

寻找右边界思路:
• 寻右左边界:
◦ ⽤ resRight 表⽰右边界;
◦ 我们注意到右边界的特点:
▪ 左边区间 (包括右边界) [left, resRight] 都是⼩于等于 x 的;
▪ 右边区间 [resRight+ 1, right] 都是⼤于 x 的;
• 因此,关于 mid 的落点,我们可以分为下⾯两种情况:
◦ 当我们的 mid 落在 [left, resRight] 区间的时候,说明 [left, mid - 1]( mid 不可以舍去,因为有可能是最终结果) 都是可以舍去的,此时更新 left 到 mid的位置; 当 mid 落在 [resRight+ 1, right] 的区间的时候,说明 [mid, right] 内的元素
是可以舍去的,此时更新 right 到 mid - 1 的位置;
• 由此,就可以通过⼆分,来快速寻找右边界;
注意:这⾥找中间元素需要向上取整。
因为后续移动左右指针的时候:
• 左指针: left = mid ,可能会原地踏步(⽐如:如果向下取整的话,如果剩下 1,2 两个元素, left == 1, right == 2,mid == 1 。更新区间之后, left,right,mid 的值
没有改变,就会陷⼊死循环)。
• 右指针: right = mid - 1 ,是会向前移动的,因此区间是会缩⼩的;
因此⼀定要注意,当 right = mid 的时候,要向下取整。

3、代码实现

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        if(nums.size()==0)  return {-1,-1};
        int left=0,right=nums.size()-1,begin=0;
        while(left<right)
        {
            int mid=left+(right-left)/2;
            if(nums[mid]<target) left=mid+1;
            else right=mid;
        }
        if(nums[left]!=target) return{-1,-1};
        else begin=left;

        left=0,right=nums.size()-1;
        while(left<right)
        {
            int mid=left+(right-left+1)/2;
            if(nums[mid]<=target) left=mid;
            else right=mid-1;
        }
        return {begin,right};
    }
};

三、X的平方根

1、题目讲解

在这里插入图片描述

2、算法原理

设 x 的平⽅根的最终结果为 index :
a. 分析 index 左右两次数据的特点:
▪ [0, index] 之间的元素,平⽅之后都是⼩于等于 x 的;
▪ [index + 1, x] 之间的元素,平⽅之后都是⼤于 x 的。

3、代码实现

class Solution {
public:
    int mySqrt(int x) {
        if(x>=0 && x<1)  return 0;
        int left=1,right=x;
        while(left<right)
        {
            long long mid=left+(right-left+1)/2;
            if(mid*mid<=x) left=mid;
            else right=mid-1;
        }
        return left;

    }
};

四、搜索插入位置

1、题目讲解

在这里插入图片描述

2、算法原理

a. 分析插⼊位置左右两侧区间上元素的特点:
设插⼊位置的坐标为 index ,根据插⼊位置的特点可以知道:
• [left, index - 1] 内的所有元素均是⼩于 target 的;
• [index, right] 内的所有元素均是⼤于等于 target 的。
b. 设 left 为本轮查询的左边界, right 为本轮查询的右边界。根据 mid 位置元素的信
息,分析下⼀轮查询的区间:
▪ 当 nums[mid] >= target 时,说明 mid 落在了 [index, right] 区间上,
mid 左边包括 mid 本⾝,可能是最终结果,所以我们接下来查找的区间在 [left, mid] 上。因此,更新 right 到 mid 位置,继续查找。
▪ 当 nums[mid] < target 时,说明 mid 落在了 [left, index - 1] 区间上,
mid 右边但不包括 mid 本⾝,可能是最终结果,所以我们接下来查找的区间在 [mid+ 1, right] 上。因此,更新 left 到 mid + 1 的位置,继续查找。
c. 直到我们的查找区间的⻓度变为 1 ,也就是 left == right 的时候, left 或者right 所在的位置就是我们要找的结果。

3、代码实现

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left=0,right=nums.size()-1;
        while(left<right)
        {
            int mid=left+(right-left)/2;
            if(nums[mid]<target) left=mid+1;
            else right=mid;
        }
        if(nums[left]<target) return left+1;
        else return left;
    }
};


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

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

相关文章

Frappe Charts:数据可视化的强大工具

一、产品简介&#xff1a; 一个简单、零依赖、响应式的 开源SVG 图表库。这个图表库无论是数据更新还是屏幕大小变化&#xff0c;都能快速响应并更新图表。数据生成和悬停查看都有舒服的交互动效&#xff0c;体验感很好。不仅支持配置颜色&#xff0c;外观定制也很方便。还支持…

Python 常用模块Logging

Python 常用模块Logging 【序言】 logging模块是专门用来做日志记录的模块 【一】日志等级 默认打印结果到终端上 CRITICAL 50 # 致命错误 ERROR 40 # 错误 WARNING 30 # 警告 INFO 20 # 消息 DEBUG 10 # 调试 NOTSET 0 # 不设置示例&#xff1a; 默认级别为…

Vue3+ElementPlus: 给点击按钮添加触发提示

一、需求 在Vue3项目中&#xff0c;有一个下载按钮&#xff0c;当鼠标悬浮在按钮上面时&#xff0c;会出现文字提示用户可以点击按钮进行数据的下载技术栈 Vue3 ElementPlusTooltip组件 ElementPlus中的Tooltip组件 &#xff0c;可用于展示鼠标 hover 时的提示信息 二、实现…

jenkins解决工具找不到的问题

--------------------------插件选择版本最好能跟服务器对上

EDM打开率突然下降的原因:深入分析并采取应对措施

在跨境电商和出海领域&#xff0c;电子邮件营销&#xff08;Email Marketing&#xff09;已成为企业营销推广及与客户互动的主要手段之一&#xff0c;在企业营销中起到主导地位。但是&#xff0c;有时我们不得不面对EDM打开率突然下降的困境。那么&#xff0c;EDM打开率下降的原…

二叉树数据结构:深入了解二叉树的概念、特性与结构

在探索栈和队列之后&#xff08;大家可以移步至我的数据结构专栏&#xff09;&#xff1a;T-rLN的数据结构专栏 我们转向了更为复杂而有趣的数据结构——二叉树。本文将引领我们进入二叉树的世界&#xff0c;从最基本的概念和结构开始&#xff0c;逐步深入了解二叉树的顺序结构…

可用于blender制作3D动画的全身动捕设备

随着动捕设备的进步&#xff0c;在3D建模和动画制作领域中&#xff0c;动捕设备被广泛应用&#xff0c;以便创建更加真实和自然的角色动画。其中&#xff0c;blender作为一款开源的3D建模和动画软件&#xff0c;搭配全身动捕设备使用&#xff0c;更加激发了用户角色动画创作灵感…

【ARMv8M Cortex-M33 系列 2 -- Cortex-M33 JLink 连接 及 JFlash 烧写介绍】

文章目录 Jlink 工具JLink 命令行示例JFlash 烧写问题Jlink 工具 J-Link 是 SEGGER 提供的一款流行的 JTAG 调试器,它支持多个平台和处理器。JLink.exe 是 J-Link 调试器的命令行接口,它允许用户通过命令行执行一系列操作,例如编程、擦除、调试等。 工具链接: https://ww…

使用VMware创建CentOS7虚拟机详细教程

创建虚拟机 首先以管理员身份运行vmware17&#xff0c;进入后点击创建虚拟机。 直接点击下一步&#xff0c;开始自定义安装。 继续点击下一步 提前将iso文件准备好&#xff0c;这里用的是centos7&#xff0c;也可以使用其他系统的文件&#xff0c;然后点击下一步。 下来就是修…

IDEA、VSCode等快速连接Github(Mac版)

问题描述 在本地书写✍️完代码后, 想要git push到Github上面, 出现延迟错误; 导致经常push不上去, 如下图所示; 解决方案 进入电脑终端; 输入下列命令; sudo vim /etc/hosts输入密码; 按下 I 键, 进行编辑操作; 将下列语句复制到空白区, 然后按下esc按键, 然后输入:wq即可…

【计算机毕业设计】SSM医疗药品采购系统

项目介绍 ssm医疗药品采购系统。主要功能有&#xff1a; 用户管理&#xff1a;管理员列表&#xff1b; 采购管理&#xff1a;采购列表&#xff1b; 药品出库&#xff1a;药品出库&#xff1b; 库存管理&#xff1a;库存统计&#xff1b; 数据维护&#xff1a;药品列表、仓库…

计算机组成原理——存储器41-60

67、下列有关RAM和ROM得叙述中正确的是(A )。 I RAM是易失性存储器&#xff0c;ROM是非易失性存储器 II RAM和ROM都是采用随机存取方式进行信息访问 III RAM和ROM都可用做Cache IV RAM和ROM都需要进行刷新 A、 仅I和II B、仅I和III C、仅I &#xff0c;II&#xff0c; I…

Python:正则表达式速通,码上上手!

1前言 正则表达式&#xff08;Regular Expression&#xff09;是一种用来描述字符串模式的表达式。它是一种强大的文本匹配工具&#xff0c;可以用来搜索、替换和提取符合特定模式的文本。 正则表达式由普通字符&#xff08;例如字母、数字、符号等&#xff09;和元字符&#…

代码审计必要性探讨

1、背景 为了保证代码的质量&#xff0c;需要一系列的流程来进行保证&#xff1a; 今天要探讨的是代码审计的必要性。 2、代码审计 代码审计的做法多种多样&#xff0c;我理解必须解决以下问题 &#xff0c;才可能有效&#xff1a; 核心&#xff1a;审计的本质是对比&#…

SAP FI会计凭证的更改记录与EDI

要求当会计凭证进行增删改时&#xff0c;把会计凭证的内容记录到自定义表中&#xff0c;以便用后其它BW抽取&#xff0c; 一开始想到的当然是SAP标准记录的更改记录表&#xff1a;CDHDR&#xff0c;CDPOS表了&#xff0c;测试发现对会计凭证BKPF,BSEG的修改&#xff08;增加&a…

ubuntu22下安装minconda

bing 搜索 canda install 找到官方网站 https://docs.conda.io/projects/miniconda/en/latest/ 这里我们安装minconda。 官网有安装方法。 mkdir -p ~/miniconda3 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh…

Docker 部署RAP2

1、Github介绍 https://github.com/thx/rap2-delos 2、安装Docker环境 yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum install -y docker-ce systemctl enable…

开发小程序和APP有什么区别?各自有什么优势?

开发小程序和APP的区别 ​ 用户范围&#xff1a;小程序主要针对微信用户&#xff0c;而APP则面向所有智能手机用户。 开发周期&#xff1a;小程序的开发周期相对较短&#xff0c;因为其基于微信平台等APP应用里的轻量级应用&#xff0c;有自身的开发规范要求。而APP开发则需要…

解决IDEA 不能正确识别系统环境变量的问题

问题描述 本人laptop 上的是设置了GOOGLE_APPLICATION_CREDENTIALS 这个环境变量的&#xff0c; 正常java or python 的程序能基于这个环境变量使用 某个gcp service account 去访问GCP的资源 [gatemanmanjaro-x13 ~]$ env | grep -i google GOOGLE_APPLICATION_CREDENTIALS/…

进程间通信---共享内存

共享内存的概念 共享内存 原理&#xff1a; 实现共享内存的步骤&#xff1a; 创建共享内存shmget&#xff08;&#xff09; 映射 共享内存 什么是映射&#xff1a;共享内存 映射 在不同进程中的地址不同。 把共享内存 从进程地址空间中脱离