二分查找——OJ题(一)

在这里插入图片描述


📘北尘_:个人主页

🌎个人专栏:《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.mzph.cn/news/583872.shtml

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

相关文章

Mini MyBatis-Plus(下)

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 最核心的内容前两篇已经…

docker 安装可视化工具 Protainer 以及 汉化

一、创建保存数据的卷 安装网址&#xff1a;Install Portainer BE with Docker on Linux - Portainer Documentation docker pull portainer/portainer二、根据portainer镜像创建容器 docker run -d -p 8000:8000 -p 9000:9000\ --name portainer --restartalways \ -v /var/r…

深入ArkUI:深入实战组件text和text input

文章目录 Text组件介绍Text组件的属性方法Text:文本显示组件4.3TextInput组件实战案例:图片宽度控制页面本文总结要点回顾在今天的课程中,我们将深入学习ArkUI提供的基础组件,着重探讨text和text input两个组件。 Text组件介绍 Text组件是一个用于显示文本的组件,其主要作…

VSCode安装Go环境

VSCode安装Go 1.点击Go官网&#xff0c;根据自己环境下载go安装包&#xff0c;我这里为Windows 2.双击安装包&#xff0c;一直点击【Next】即可 VSCode配置Go基础环境 1.创建Go的工作目录: C:\Code\GoCode 2.创建Go的环境变量: GOPATH (1)右键【此电脑】&#xff0c;点击…

C/C++转WebAssembly及微信小程序调用

上一篇文章讲了C/C如何转WebAssembly&#xff0c;并测试了在Web端调用。本篇内容和上篇一样&#xff0c;介绍C/C包转的.wasm包如何在小程序中调用。 说明 本篇是在上一篇步骤1-4的基础上&#xff0c;再做修改&#xff0c;供微信小程序端调用的方法和步骤。 本篇操作手册可以…

Python自动化测试:选择最佳的自动化测试框架

在开始学习python自动化测试之前&#xff0c;先了解目前市场上的自动化测试框架有哪些&#xff1f; 随着技术的不断迭代更新&#xff0c;优胜劣汰也同样发展下来。从一开始工具型自动化&#xff0c;到现在的框架型&#xff1b;从一开始的能用&#xff0c;到现在的不仅能用&…

鸿蒙问题之本地模拟器无法识别

今天按例打开本地模拟器&#xff0c;发现DevEco Studio不能检测到我的本地模拟器了。 重启了DevEco Studio和模拟器多次都无果。果断删除模拟器 然后创建一个新的&#xff0c;就可以成功检测到了。这应该是idea的一个bug

关于python解析mf4中二维信号数据的注意事项

python解析mf4中的信号数据一般用np.ndarray存储&#xff0c;但是mf4中的一个信号有时不一定是一维数据&#xff0c;有时会是一个二维的&#xff0c;没错&#xff0c;就是一个信号数据就是二维的&#xff0c;这时候&#xff0c;np数组的每个元素也是一个数组&#xff0c;这个时…

【揭秘】如何制作推拉门电子画册,轻松成为行业大咖!

​在当今数字化时代&#xff0c;电子画册已成为企业展示产品、服务的重要手段。与传统印刷画册相比&#xff0c;电子画册具有诸多优势&#xff0c;如易于传播、易于更新、环保低碳等。更重要的是&#xff0c;通过电子画册&#xff0c;企业可以更好地与目标受众互动&#xff0c;…

天津医科大学临床医学院专升本药学专业有机化学考试大纲

天津医科大学临床医学院高职升本科专业课考试大纲药学专业《有机化学》科目考试大纲 一、考试基本要求 本考试大纲主要要求考生对《有机化学》基本概念有较深入的了解&#xff0c;能够系统地掌握各类化合物的命名、结构特点及立体异构、主要性质、反应、来源和合成制备方法等…

相对于一般的统计学,计量经济学的特色是什么?谈Stata与计量经济学

Stata作为一种数据分析软件&#xff0c;高度适用于依托计量经济学的研究领域&#xff0c;如宏观经济学、财政学等&#xff0c;当然在医学等学科应用也较为广泛&#xff0c;在处理面板数据方面也深具特色。计量经济学是指运用概率统计方法对经济变量之间的因果关系进行定量分析的…

idea的pom.xml文件灰色删除线解决办法

以上是点击了移除module后就变成这样 如果再次对着已移除的module右键会发现有个delete&#xff0c;点击这个是真删了&#xff0c;要谨慎备份哦 解决方案&#xff1a;恢复误操作remove module的解决方法 idea最右边&#xff0c;有个Maven控件&#xff0c;找到要恢复的module&a…

vscode连接linux服务器

目录 下载vscode&#xff0c;这是微软开源软件&#xff0c;打开后到下载扩展页面 在下载扩展页面下载中文和ssh远程连接扩展 安装后会在左边新生成一个图标点击齿轮 选择第一个 配置连接信息 远程隧道右边刷新&#xff0c;等刷出来hostname的主机后 连接ip出来后&#x…

mybatisX自动生成sql语句,尝试测试方法报错

今天我使用mybatisx自定义mapper方法生成sql语句后&#xff0c;在测试时报错 错误是MyBatis 无法找到映射的语句&#xff08;Statement&#xff09;引起的 我是这样操作的&#xff0c;在mapper接口自定义了一个方法 然后alt加enter&#xff0c;自动生成sql 结果 mapper.xml文件…

骨传导耳机的原理是什么?一文读懂骨传导耳机优缺点都有哪些!

一、骨传导耳机传声原理是什么 骨传导耳机以人体骨骼为传声介质&#xff0c;可以将声音转化为不同频率的震动&#xff0c;在不经过外耳道和鼓膜的情况下&#xff0c;通过震动使声音经过内耳道&#xff0c;直接传入大脑听觉神经&#xff0c;与传统耳机相比&#xff0c;可以节省许…

Gooxi成功入选全国首批人工智能企业

日前&#xff0c;Gooxi成功入选由深圳市人工智能产业协会评定的全国首批36家人工智能企业之一&#xff0c;这是继Gooxi成功与广东未来研究院合作AI联合创新中心之后在AI行业持续深耕的又一殊荣&#xff0c;彰显出Gooxi在AI领域的卓越实力。 据悉&#xff0c;全国首批人工智能企…

第 1 场 算法季度赛 蓝桥搜狐畅游(1~5 , 7)

1、水题 2、树上dp 3、模拟 4、概率 5、拆位 6、&#xff08;是没学过的东西了...&#xff09; 7、组合数学 1. 新年快乐【算法赛】 直接模拟 #include <iostream> using namespace std; int main() {cout <<"2024 AK";return 0; } 2. 蓝桥圣诞树…

【每日一题】收集巧克力

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;枚举操作数 写在最后 Tag 【枚举】【数组】【2023-12-28】 题目来源 2735. 收集巧克力 题目解读 有长度为 n, 下标从 0 开始的整数数组 nums, 表示收集不同类型的巧克力的成本. nums[i] 表示收集类型 i 巧克力的成本…

12.28_黑马数据结构与算法笔记Java

目录 291 最长公共子序列 动态规划 分析 292 最长公共子序列 动态规划 实现 293 Leetcode 583 两个字符串删除 294 Leetcode 300 最长递增子序列 分析 295 Leetcode 300 最长递增子序列 实现 296 Catalan数 分析 297 Catalan数 实现 298 Catalan数 应用 出栈总数 299 C…

【C++】vector 基本使用(详解)

目录 一&#xff0c;vector 的介绍 二&#xff0c;vector 的定义 1&#xff0c;vector() 2&#xff0c;vector&#xff08;size_type n, const value_type& val value_type()&#xff09; 3&#xff0c;vector (const vector& x) 4&#xff0c;vector (InputIte…