【优选算法必刷100题】第019~20题(二分查找算法):x 的平方根、搜索插入位置

【优选算法必刷100题】第019~20题(二分查找算法):x 的平方根、搜索插入位置

🔥艾莉丝努力练剑:个人主页

专栏传送门:《C语言》《数据结构与算法》C/C++干货分享&学习过程记录Linux操作系统编程详解笔试/面试常见算法:从基础到进阶

⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平


🎬艾莉丝的简介:


🎬艾莉丝的算法专栏简介:


目录

019  x 的平方根

1.1  思路一:暴力解法

1.1.1  算法思路

1.1.2  算法实现

1.2  思路二:二分查找

1.2.1  算法思路

1.2.2  算法实现

1.3  博主手记

020  搜索插入位置

2.1  算法思路——二分查找

2.2  算法实现

2.3  博主手记

结尾



019  x 的平方根

力扣链接:69. x 的平方根

力扣题解链接:二分查找算法模版解决【x 的平方根 】问题

题目描述:

1.1  思路一:暴力解法

1.1.1  算法思路

依次枚举 [0,x] 之间的所有数 (这里没有必要研究是否枚举到x / 2还是x / 2 + 1。因为我们找到结果之后直接就返回了,往后的情况就不会判断。反而研究枚举区间,既耽误时间,又可能出错):

(1)如果i * i == x,直接返回;
(2)如果i * i > x,说明之前的一个数是结果,返回i - 1。

由于i * i可能超过int的最大值,因此使用 long long类型。

1.1.2  算法实现

代码演示如下——

class Solution { public: int mySqrt(int x) { // 由于两个较⼤的数相乘可能会超过 int 最⼤范围 // 因此⽤ long long long long i = 0; for (i = 0; i <= x; i++) { // 如果两个数相乘正好等于 x,直接返回 i if (i * i == x) return i; // 如果第⼀次出现两个数相乘⼤于 x,说明结果是前⼀个数 if (i * i > x) return i - 1; } // 为了处理oj题需要控制所有路径都有返回值 return -1; } };
时间复杂度:O(n),空间复杂度:O(1)。

1.2  思路二:二分查找

1.2.1  算法思路

设x的平方根的最终结果为index——

1、分析index左右两次数据的特点:

(1)[ 0 , index ] 之间的元素,平方之后都是小于等于x的;
(2)[ index + 1 , x] 之间的元素,平方之后都是大于的。

因此可以使用二分查找算法

1.2.2  算法实现

代码演示如下——

class Solution { public: int mySqrt(int x) { if(x < 1) return 0; // 处理边界情况 int left = 1,right = x; while(left < right) { long long mid = left + (right - left + 1) / 2; // 数据量大,类型改成long long更加合适,防溢出 if(mid * mid <= x) left = mid; else right = mid - 1; } return left; } };
时间复杂度:O(logn),空间复杂度:O(1)。

1.3  博主手记

本题整个的思路、算法原理、解题过程博主在纸上推导了一遍,大家可以参考一下手记的推导过程!最好做题的过程中自己也推导一遍!!!自己能够推导很重要!


020  搜索插入位置

力扣链接:35. 搜索插入位置

力扣题解链接:二分查找模版解决【搜索插入位置】问题

题目描述:

2.1  算法思路——二分查找

1、分析插入位置左右两侧区间上元素的特点——
设插入位置的坐标为index,根据插入位置的特点可以知道:

(1)[left,index-1]内的所有元素均是小于target的;
(2)[index,right]内的所有元素均是大于等于target的。

2、设 left 为本轮查询的左边界,right为本轮查询的右边界。根据mid位置元素的信息,分析下一轮查询的区间:

(1)当nums[mid] >= target时,说明mid落在了[index , right]区间上,mid左边包括mid本身,可能是最终结果,所以我们接下来查找的区间在[left,mid]上。因此,更新right到mid位置,继续查找;

(2)当nums[mid] < target时,说明mid落在了([left , index - 1]区间上,mid右边但不包括mid本身,可能是最终结果,所以我们接下来查找的区间在[mid + 1 , right]上。因此,更新[left到mid+1的位置,继续查找。

3、到我们的查找区间的长度变为1,也就是left == right的时候,left 或者 right 所在的位置就是我们要找的结果。

2.2  算法实现

代码演示如下——

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; } };

left和right这里已经相遇了,返回left或者right都是可以的——

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[right] < target) return right + 1; else return right; } };
时间复杂度:O(logn),空间复杂度:O(1)

2.3  博主手记

本题整个的思路、算法原理、解题过程博主在纸上推导了一遍,大家可以参考一下手记的推导过程!最好做题的过程中自己也推导一遍!!!自己能够推导很重要!


结尾

往期回顾:

【优选算法必刷100题】第018题(二分查找算法):在排序数组中查找元素的第一个和最后一个位置

结语:都看到这里啦!请大佬不要忘记给博主来个“一键四连”哦!

🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡

૮₍ ˶ ˊ ᴥ ˋ˶₎ა


Read more

具身智能探索:从感知到行动的机器人实践

具身智能探索:从感知到行动的机器人实践

文章目录 * 每日一句正能量 * 引言 * 什么是具身智能? * 初探具身智能:一个简单的四足机器人案例 * 环境搭建 * 感知:用摄像头和深度传感器采集环境信息 * 推理:基于深度强化学习的决策 * 行动:控制四足机器人动态行走 * 图片展示 * 总结与展望 每日一句正能量 没有人会为了你的未来买单,你要么努力向上爬,要么烂在社会最底层的泥淖里,这就是生活。 引言 近年来,“具身智能”成为机器人领域的热门话题,它不仅仅是让机器人“看起来像人”,而是让机器人通过身体与环境的交互,真正“理解”并“学习”世界。这篇文章将带领大家一起探索具身智能的核心思想,并通过一个简单的机器人项目,从感知、推理到行动,完整展示如何构建一个具身智能系统。本文还包含代码片段和实验图片,希望能帮助你更直观地理解这一前沿技术。 什么是具身智能? 具身智能(Embodied Intelligence)的核心理念是:智能来源于身体与环境的交互,而非仅仅依赖于抽象的计算能力。这个思想最早由人工智能哲学家罗德尼·布鲁克斯提出,他认为传统的“感知-思考-行动”

By Ne0inhk
【MySQL】第十三节—索引:底层原理、B + 树演进、操作实战

【MySQL】第十三节—索引:底层原理、B + 树演进、操作实战

Hello,好久不见,我是云边有个稻草人-个人主页,与你分享C++领域专业知识! 《MySQL》——本篇文章所属专栏,持续更新中 本文深入解析MySQL索引原理与操作。首先通过实验展示数据默认有序现象,解释Page机制减少IO次数的原理。然后循序渐进分析B+树结构的优势:从单页线性遍历、引入目录到多级目录页构建,最终形成高效的B+树索引。文章对比了B+树与B树、哈希等结构的差异,阐述聚簇索引与非聚簇索引的本质区别。在操作层面,详细介绍了主键索引、唯一索引、普通索引和全文索引的创建与删除方法,并给出索引使用原则:频繁查询字段适合建索引,但更新频繁或唯一性差的字段不宜建索引。最后提及复合索引的最左匹配原则和索引覆盖优化技巧。 【MySQL】第十二节—不懂磁盘与 Page,谈何用好 MySQL 索引?——索引上篇 目录 5. 索引的理解 (1)一个现象和一个结论 (2)循序渐进,理解索引的数据结构为什么选择B+树 第一层—线性遍历效率低下 第二层—引入目录

By Ne0inhk
Android 蓝牙 BLE 扫描 Native 层架构与扫描流程剖析

Android 蓝牙 BLE 扫描 Native 层架构与扫描流程剖析

博主简介 byte轻骑兵,现就职于国内知名科技企业,专注于嵌入式系统研发,深耕 Android、Linux、RTOS、通信协议、AIoT、物联网及 C/C++ 等领域。乐于技术分享与交流,欢迎关注互动! 📌 主页与联系方式ZEEKLOG:https://blog.ZEEKLOG.net/weixin_37800531知乎:https://www.zhihu.com/people/38-72-36-20-51微信公众号:嵌入式硬核研究所邮箱:[email protected](技术咨询或合作请备注需求) ⚠️ 版权声明 本文为原创内容,未经授权禁止转载。商业合作或内容授权请联系邮箱并备注来意。 本文基于 Android 蓝牙源码中 BLE 扫描相关的 Native 层代码,以scanInitializeNative为入口,系统梳理 BLE 扫描从 JNI

By Ne0inhk