二分查找(2)

news2024/9/28 16:09:55

目录

x 的平方根

题解: 

山脉数组的峰顶索引(数组内只有一个峰值)

 题解:

寻找峰值(数组内有多个峰值)

题解: 

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

题解: 

点名

题解:


怎么判断 left = mid 、left = mid+1 (right = mid、right = mid -1 )?

如果 mid 位置可能存在正确答案,那么 mid 位置不能舍去(left = mid ,right = mid);

如果 mid 位置一定不是正确答案,则 mid 位置要舍去(left = mid+1 、right = mid -1 )!

x 的平方根

69. x 的平方根 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/sqrtx/description/

题解: 

由于求的是 x 的平方根的整数部分,假设 x 的平方根的整数部分为 ret,则 [ 1 , ret ] 区间内的数的平方一定小于等于 x[ ret+1 , x ] 区间内的数的平方一定大于 x。根据这个二段性我们可以用二分查找解决本题。

假设初始时 left = 1,right = x

  • 如果 mid*mid > x ,right = mid-1,mid 位置需要舍去 ; 
  • 如果 mid*mid <= x , left = mid,mid 的平方可能是正确答案,该位置不可以舍去.
  • 由于 right = mid-1 (不是 mid),所以 mid = left + (right - left+1)/2
  • 当 left 和 right 相遇时(指向同一个位置),该位置就是正确答案。

为什么 left 和 right 相遇时就是正确答案呢?

假设一开始 left 、mid、right 连续且相邻,此时 x 的平方根的整数部分就在这三个数之中!

如果 mid*mid > x,那么 right 就会和 left 指向同一个位置,而 left*left <= x,比 left 小的数的平方(即 left 左边的数的平方)一定小于 x,left 的平方最接近 x,没有继续迭代的必要了(继续迭代的话,要么 mid*mid <= x ,left = mid,进入死循环,要么 mid*mid > x ,right = mid-1,right 跑到 left 的左边,right*right < x,违背了 right*right > x 的原则)此时 x 的平方根就是 left;

如果 mid*mid <= x,走到第 3 步时,出现两种情况,

1、mid*mid <= x(即第 4 步),left = mid,left 和 right 指向同一个位置,同样的,比 left 小的数的平方(即 left 左边的数的平方)一定小于 x,left 的平方最接近 x。

2、mid*mid > x(即第 5 步),right = mid -1,分析见上。

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

山脉数组的峰顶索引(数组内只有一个峰值)

852. 山脉数组的峰顶索引 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/peak-index-in-a-mountain-array/description/

 题解:

同样的,可以把山脉数组分为两部分,以峰顶作为分界线,峰顶左边的数(包括峰顶)在不断递增,峰顶右边的数(不包括峰顶)在不断递减。也就是把数组分为递增数组和递减数组!

假设初始时 left = 0,right = arr.size() -1

利用在递增数组中,后一个数大于前一个数,在递减数组中,后一个数小于前一个数可得:

  • 如果 arr[ mid-1 ] >= arr[ mid ]  (位于递减数组),right = mid-1,mid 位置需要舍去 ; 
  • 如果 arr[ mid-1 ] < arr[ mid ]  (位于递增数组), left = mid,mid 的平方可能是正确答案,该位置不可以舍去.
  • 由于 right = mid-1 (不是 mid),所以 mid = left + (right - left+1)/2
  • 当 left 和 right 相遇时(指向同一个位置),该位置就是正确答案。
class Solution {
public:
    int peakIndexInMountainArray(vector<int>& arr) {
        int left=0,right=arr.size()-1;
        while(left<right)
        {
            int mid=left+(right-left+1)/2;
            if(arr[mid-1]<arr[mid]) left=mid;
            else    right=mid-1;
        }
        return left;
    }
};

寻找峰值(数组内有多个峰值)

162. 寻找峰值 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/find-peak-element/description/

题解: 

和上一题一样,峰顶左边的数(包括峰顶)在不断递增,峰顶右边的数(不包括峰顶)在不断递减,也就是把数组分为递增数组和递减数组!由于数组中可能存在多个峰值,也就是说,可以划分为多个递增数组和递减数组

假设初始时 left = 0,right = nums.size() -1

利用在递增数组中,后一个数大于前一个数,在递减数组中,后一个数小于前一个数可得:

  • 如果 nums[ mid ] > nums[ mid+1 ]  (位于递减数组),说明我们当前位于其中一个山脉中,我们就专注于找到当前山脉的峰顶,其他山脉的峰顶我们就不管了right = mid(mid 位置不可以舍去),把 mid 右边的山脉都忽略掉 ; 
  • 如果nums[ mid ] <= nums[ mid+1 ]  (位于递增数组),同样的也只找当前山脉的峰顶, left = mid+1,mid 位置可以舍去.
  • 由于 right = mid (不是 mid -1),所以 mid = left + (right - left)/2
  • 当 left 和 right 相遇时(指向同一个位置,在峰顶相遇),该位置就是正确答案。
class Solution {
public:
    int findPeakElement(vector<int>& nums) {
        int left=0,right=nums.size()-1;
        while(left<right)
        {
            int mid=left+(right-left)/2;
            if(nums[mid]>nums[mid+1])   right=mid;
            else    left=mid+1;
        }
        return left;
    }
};

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

153. 寻找旋转排序数组中的最小值 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/find-minimum-in-rotated-sorted-array/description/

题解: 

原本数组是升序排序的,旋转后,数组就被分成了两个递增数组。

如下图所示,数组被切分后,可以分为两个递增数组,以切分后的数组的最后一个数字 D 为基准,第一个递增数组内的数字都大于 D,第二个递增数组内的数字都小于 D,旋转后的数组的最小值就在第二个递增数组中,利用这个二段性,就解决这道题。


假设初始时 left = 0,right = nums.size() -1 , 基准数为 nums[ n-1 ] ( n=nums.size() ),

  • 如果 nums[ mid ] > nums[ n-1 ] ,说明我们现在位于第一个递增数组left = mid+1,mid 位置要舍掉,向第二个递增数组逼近;
  • 如果 nums[ mid ] <= nums[ n-1 ],说明我们现在位于第二个递增数组right = mid,向这个数组的最小值逼近,mid 位置不可以舍去。
class Solution {
public:
    int findMin(vector<int>& nums) {
        int left=0,right=nums.size()-1,n=nums.size();
        while(left<right)
        {
            int mid=left+(right-left)/2;
            if(nums[mid]>nums[n-1]) left=mid+1;
            else    right=mid;
        }
        return nums[left];
    }
};

 

点名

LCR 173. 点名 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/que-shi-de-shu-zi-lcof/description/

题解:

本道题有多种解法,这里提供二分查找的解决。

根据下图数组可以发现,我们缺的数字是 3 ,比 3 小的数字和数字对应的下标是相等的,比 3 大的数字比数字对应的下标大。缺失数字的右边第一个数字的下标恰好为缺失数字!

根据这个二段性,假设初始时 left =0,right = records.size() -1,

  • 如果 records[ mid ] == mid,说明缺失的数字在 mid 的右边,left = mid + 1,mid位置要舍去;
  •  如果 records[ mid ] != mid,说明缺失的数字在 mid 的左边,或者就在 mid 位置,所以 mid 位置不能舍去,right = mid。
  • 由于 right = mid (不是 mid -1),所以 mid = left + (right - left)/2
  • 当 left 和 right 相遇时:如果 records[ left ] == left ,说明它们在缺失数字的左边相遇了,则缺失数字为 left+1;如果 records[ left ] != left,说明它们在缺失数字的右边相遇了,则缺失数字为 left。
class Solution {
public:
    int takeAttendance(vector<int>& records) {
        int left=0,right=records.size()-1;
        while(left<right)
        {
            int mid=left+(right-left)/2;
            if(records[mid]==mid)   left=mid+1;
            else    right=mid;
        }
        return records[left]==left?left+1:left;
    }
};

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

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

相关文章

FreeRTOS 内存管理源码解析

目录 一、heap_11、源码讲解2、总结 二、heap_21、源码讲解1.1 堆的初始化1.2 内存分配1.3 内存释放 2、总结 三、heap_3四、heap_41、源码1.1 插入链表1.2 堆的初始化1.3 内存的申请1.4 内存的释放 2、总结 五、heap_51、源码1.1 堆的初始化1.2 链表的插入、内存分配、释放 2、…

五.海量数据实时分析-FlinkCDC+DorisConnector实现数据的全量增量同步

前言 前面四篇文字都在学习Doris的理论知识&#xff0c;也是比较枯燥&#xff0c;当然Doris的理论知识还很多&#xff0c;我们后面慢慢学&#xff0c;本篇文章我们尝试使用SpringBoot来整合Doris完成基本的CRUD。 由于 Doris 高度兼容 Mysql 协议&#xff0c;两者在 SQL 语法…

【滑动窗口算法】——定长滑动窗口——Python(附题)

一.定长滑动窗口是什么及其使用场景 定长滑动窗口算法的核心思想是使用两个指针&#xff0c;通常称为“左指针”和“右指针”。窗口的大小是固定的&#xff0c;右指针用于扩展窗口&#xff0c;直到达到指定大小&#xff0c;而左指针则在窗口移动时逐步向右滑动。这样可以高效地…

3款照片人物开口说话AI工具,跟真人说话一样~免费!短视频带货必备!(附教程)

大家好&#xff0c;我是画画的小强 今天给大家分享一个AI图片口播数字人讲认知思维&#xff0c;单号佣金赚5W的AI带货信息差玩法&#xff0c;许多小伙伴表示对这类AI带货玩法感兴趣。 说实话&#xff0c;现在AI照片人物对口型工具&#xff0c;越来越逼真&#xff0c;很难辨识出…

Codesys trace工具右键菜单框呼出异常的问题解决

这个问题困扰了好久&#xff0c;添加trace工具之后&#xff0c;一但在模型图位置右键后&#xff0c;整个codesys界面都无法呼出右键菜单&#xff0c;甚至会出现键盘输入失效的问题。 解决办法&#xff1a;更新trace工具 1、工具 —> CODESYS Installer 或者搜索CODESYS In…

AI新时代序幕!大模型研究报告(附AI名词详解)

AI新时代序幕&#xff01;大模型研究报告&#xff08;附AI名词详解&#xff09; 前言AI 大模型研究报告 前言 AI通过大规模的数据训练和先进的算法构建而成的&#xff0c;能够模拟人类的智能&#xff0c;处理各种复杂的任务。它可以理解我们的语言&#xff0c;回答我们的问题&…

PyQt5 statusbar 放图片并设置图片大小和左右间距

在 PyQt5 中&#xff0c;状态栏&#xff08;QStatusBar&#xff09;通常用于显示窗口的状态信息或提示。虽然 PyQt5 的 QStatusBar 没有直接提供设置图片作为状态栏项&#xff08;QStatusBarItem&#xff09;的 API&#xff0c;但你可以通过添加一个 QWidget&#xff08;如 QLa…

Java实现找色和找图功能

某天&#xff0c;张三接到一个任务需求&#xff0c;将一个Excel表格里面的员工信息&#xff0c;录入到员工系统里面&#xff0c;由于数据量非常大&#xff0c;操作起来巨慢。经过一段时间的操作和观察&#xff0c;他发现这种操作&#xff0c;非常有规律&#xff0c;基本就是一些…

html+css+js实现Pagination 分页

效果图 HTML部分 <body><div class"pagination"><button class"prev"><</button><ul><li class"active">1</li><li>2</li><li>3</li><li>4</li><li>5…

基于springboot+vue+mysql公益旧物捐赠系统(源码+参考文档+定制)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

3d可视化图片:通过原图和深度图实现

1、depthy 在线体验demo: https://depthy.stamina.pl/#/ 也可以docker安装上面服务: docker run --rm -t -i -p 9000:9000 ndahlquist/depthy http://localhost:90001)首先传原图 2)再传对应深度图 3)效果

云栖大会观察:云计算第三次浪潮下的暗流涌动

如果跳脱出今年云栖大会的“云启智跃产业蝶变”、“云计算第三次浪潮”这些设定好的视角&#xff0c;站在“AI有着太多的未知性”这个角度观察这次大会&#xff0c;会看到什么&#xff1f; 我们会看到&#xff0c;对于现在的阿里云而言&#xff0c;AI带来的并非都是机遇&#…

【Gitee自动化测试4】本地Git分支的增删查,本地Git分支中文件的增删查,本地文件的暂存/提交,本地分支的推送

一、流程 本地创建分支&#xff0c;设定连接什么云分支本地创建文件&#xff0c;暂存、提交–>本地分支本地分支推送所有修改–>云仓库 二、分支概念 在版本回退里&#xff0c;每次提交&#xff0c;git都把它们串成一条时间线&#xff0c;这条时间线可以理解为是一个分…

Meta Sapiens 人体AI模型

Meta 一直是开发图像和视频模型的领导者&#xff0c;现在他们又增加了一个新东西&#xff1a;Meta Sapiens。和Homo sapiens一样&#xff0c;这个模型也是关于人类的。它旨在执行与人类相关的任务&#xff0c;例如理解身体姿势、识别身体部位、预测深度&#xff0c;甚至确定皮肤…

小学三年级数学拓展填空题

用传统思维来看小学的学习是错误的。 学校考核老师主要看学生成绩&#xff0c;导致学生作业很多。 而且&#xff0c;现在的中小学生是不是太卷了&#xff1f;都开始卷远超过自己年龄阶段应该掌握的内容了&#xff1f;——这才是很不正常的现象。 如果大家都这么卷&#xff0c…

自然资源部最新Nature正刊!!!

2024年8月21日&#xff0c;国际顶级期刊《Nature》发表了自然资源部第二海洋研究所李家彪院士为通讯作者&#xff0c;张涛为第一作者的论文“超慢速扩张加克洋中脊的高变化岩浆增生”。这一成果颠覆了国际海洋学术界半个多世纪以来一直认为的超慢速扩张洋中脊岩浆供给极度贫瘠的…

9--苍穹外卖-SpringBoot项目中Redis的介绍及其使用实例 详解

目录 Redis入门 Redis简介 Redis服务启动与停止 服务启动命令 Redis数据类型 5种常用数据类型介绍 各种数据类型的特点 Redis常用命令 字符串操作命令 哈希操作命令 列表操作命令 集合操作命令 有序集合操作命令 通用命令 在java中操作Redis Redis的Java客户端 …

excel统计分析(4): 多元线性回归分析

用途&#xff1a;研究多个自变量&#xff08;也称为预测变量或解释变量&#xff09;与一个因变量&#xff08;也称为响应变量&#xff09;之间的线性关系。 多元线性回归分析模型&#xff1a;Yβ0β1X1β2X2…βkXkϵ Y 是因变量。1,X2,…,Xk 是自变量。β0 是截距项。β1,β2,…

ROSTCM6+Gephi的网络语义分析详细教程(附案例实战)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

经济不好,但是遍地都是赚钱的机会

现在职场越来越内卷&#xff0c;裁员风波也是不断&#xff0c;前些天看到一个帖子&#xff0c;裁员都裁到应届生头上了。 都说00后整治职场&#xff0c;在如今环境下也要掂量一下了。 大家都在抱怨环境&#xff0c;可是你有没有想过&#xff0c;有些人在闷声发着小财。 下面…