【刷题】 二分查找进阶

news2024/12/28 20:13:21

在这里插入图片描述

送给大家一句话:
你向神求助是因为相信神,神没有回应你是因为神相信你

ε≡٩(๑>₃<)۶ ε≡٩(๑>₃<)۶ ε≡٩(๑>₃<)۶ 一心向学


二分查找进阶

  • 1 前言
  • Leetcode 852. 山脉数组的峰顶索引
    • 题目描述
    • 算法思路
  • Leetcode 162. 寻找峰值
    • 题目描述
    • 算法思路
  • Leetcode 153. 寻找旋转排序数组中的最小值
    • 题目描述
    • 算法思路
  • Leetcode LCR 173. 点名
    • 题目描述
    • 算法思路
  • Thanks♪(・ω・)ノ谢谢阅读!!!
  • 下一篇文章见

1 前言

二分查找的算法思想是很好理解的。朴素二分很容易,但一般常使用左端点查找与右端点查找来解决问题。
模版:

        int left = 0 , right = nums.size() - 1;
        while(left < right)
        {
            int mid = left + (right - left) / 2;
            //int mid = left + (right - left + 1) / 2;
            if(  // 判断条件 )
            {
                left = mid + 1;
                //left = mid 
            }
            else
            {
                right = mid;
                // right = mid - 1
            }
        }
        return left;
        //return right ;
  1. while()循环条件是left < right !
  2. 注意对应关系。right里有 -1 那么对应的求中值就要有+1。把握这个规律,就不会弄乱了

下面来看几道例题,强化训练二分查找的算法思路!通过这些题的训练,就可以很熟悉二分查找算法的思想,以后遇到问题就多了一种解决手段!!!

Leetcode 852. 山脉数组的峰顶索引

上链接:852. 山脉数组的峰顶索引!!!

题目描述

在这里插入图片描述
首先我们要理解什么是山峰数组,根据题目的描述,山峰数组就是先升再下降的数组。我们要在其中寻找峰值的索引。这个问题看起来看还是挺简单的

算法思路

首先我们要判断该数组是否存在二段性???
当然有了!

  • 以峰值为分割,左边都是nums[n] < nums[n + 1] 右边都是nums[n] > nums[n + 1]

通过这个二段性我们可以来进行二分查找:

  1. 如果中值落在左边,那么left 应该 移动到 mid + 1(因为nums[n] < nums[n + 1] ,mid对应的值一定不是峰值)
  2. 如果中值落在右边,那么right 应该 移动到 mid(因为nums[n] > nums[n + 1] ,mid对应的值有可能是峰值)

有了思路,代码很简单就可以写出来,直接套用模版。

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

提交:过啦!!!!

Leetcode 162. 寻找峰值

家人们!!!跟上节奏:162. 寻找峰值

题目描述

在这里插入图片描述
这道题是上面求峰值索引的变形。这道题具有多个封值(换句话说数组是无序的),那么我们要在无序的数组寻找一个峰值。

算法思路

首先我们来看可不可以判断出来数组的二段性。和求峰值索引一样:

  • 以其中一个峰值为分割,左边一部分是nums[n] < nums[n + 1] 右边一部分是nums[n] > nums[n + 1]

那么根据这个二段性也就是可以写出算法逻辑了:

  1. 如果中值落在左边,那么left 应该 移动到 mid + 1(因为nums[n] < nums[n + 1] ,右边一定存在一个峰值,mid对应的值一定不是峰值)
  2. 如果中值落在右边,那么right 应该 移动到 mid(因为nums[n] > nums[n + 1] ,左边一定存在一个峰值,mid对应的值有可能是峰值)

有了思路,直接套用模版秒了!!!

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])
            {
                left = mid + 1;
            }
            else
            {
                right = mid;
            }
        }
        return left;
    }
};

提交 过啦!!!

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

上链接!!!153. 寻找旋转排序数组中的最小值

题目描述

在这里插入图片描述
根据题目描述啊,是很好理解的,就是将一个有序的数组进行移动,使其旋转,形成一个先增长然后断崖后再增长的数组,我们要找到其中的最小值

算法思路

这个题的暴力算法很简单(我们不考虑),首先也是来分析二段性。这个二段性如何进行分析呢???

  • 以其中 数组末位值为分割,由于旋转的特性,左边一部分是大于末位值 右边一部分是小于等于末位值

然后根据二段性进行算法分析:

  1. 如果中值落在左边,那么left 应该 移动到 mid + 1(左边一定不存在最小值,mid 对应的值一定不是最小值)
  2. 如果中值落在右边,那么right 应该 移动到 mid(右边一定不存在一个峰值,mid对应的值有可能是最小值)

根据算法逻辑,直接秒杀:

class Solution {
public:
    int findMin(vector<int>& nums) {
        //分析二段性质
        //左边都大于 末位数字 右边都 小于等于 末尾数字
        int left = 0;
        int right = nums.size() - 1;

        while(left < right)
        {
            int mid = left +(right - left) / 2;
            //说明mid 在最小值 左边 
            if(nums[mid] > nums[nums.size() - 1])
            {
                left = mid + 1;
            }
            else
            {
                right = mid;
            }
        }
        return nums[left];
    }
};

提交:过啦!!!

Leetcode LCR 173. 点名

最后一道:LCR 173. 点名!!!

题目描述

在这里插入图片描述
题目非常简单奥,就是寻找断点。(有坑哦)

算法思路

暴力算法有很多种:遍历,位运算,数学公式。我们来用更快速的二分查找算法
首先来分析二段性,这个其实不太好想

  • 以其中断点为分割,左边一部分是数组值与下标相等 ,右边一部分是数组值与下标不相等

根据这个二段性我们就可以来进行算法分析:

  1. 如果中值落在左边,那么left 应该 移动到 mid + 1(左边一定不存在断点,mid 对应的值一定不是断点)
  2. 如果中值落在右边,那么right 应该 移动到 mid(mid对应的值有可能是断点)
  3. 注意如果最后left到了最右边,那么缺少的是最后一名同学,要进行一个判断

根据这个算法逻辑,我们书写代码:

class Solution {
public:
    int takeAttendance(vector<int>& nums) {
        //寻找二段性
        //左边下标对应 右边下标不对应
        int left = 0 ; 
        int right = nums.size() - 1;

        while(left < right)
        {
            int mid = left + (right - left ) / 2;
            //
            if(nums[mid] == mid)
            {
                left = mid + 1;
            }
            else
            {
                right = mid;
            }
        }
        //left到了最右边,缺少的是最后一名同学,要进行一个判断
        return nums[left] == left ? nums.size() : left ;
    }
};

提交过啦!!!

Thanks♪(・ω・)ノ谢谢阅读!!!

下一篇文章见

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

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

相关文章

Unity类银河恶魔城学习记录13-5,6 p146 Delete save file,p147 Encryption of saved data源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili FileDataHandler.cs using System; using System.IO; using UnityEngine; p…

Git TortoiseGit 安装使用详细教程

前言 Git 是一个免费的开源分布式版本控制系统&#xff0c;是用来保存工程源代码历史状态的命令行工具&#xff0c;旨在处理从小型到非常大型的项目&#xff0c;速度快、效率高。《请查阅Git详细说明》。TortoiseGit 是 Git 的 Windows Shell 界面工具&#xff0c;基于 Tortoi…

pg内核之日志管理器(五)WAL日志

概念 WAL日志 数据库运行过程中&#xff0c;数据一般是会保存在内存和磁盘中&#xff0c;为保证数据的安全性&#xff0c;防止数据库崩溃时数据不丢失&#xff0c;一般都是要保证数据实时落盘的&#xff0c;但是又由于磁盘随机IO读写速率与内存相比慢很多&#xff0c;如果每个…

Python爬虫爬取中药材价格数据

&#x1f388; 博主&#xff1a;一只程序猿子 &#x1f388; 博客主页&#xff1a;一只程序猿子 博客主页 &#x1f388; 个人介绍&#xff1a;爱好(bushi)编程&#xff01; &#x1f388; 创作不易&#xff1a;喜欢的话麻烦您点个&#x1f44d;和⭐&#xff01; &#x1f388;…

【Ubuntu20.04+Noetic】UR5e+Gazebo+Moveit

环境准备 创建工作空间 mkdir -p ur5e_ws/src cd ur5e_ws/srcUR机械臂软件包 UR官方没更新最新的noetic的分支,因此安装melodic,并需要改动相关文件。 安装UR的模型配置包,包里面有UR模型文件,moveit配置等: cd ~/ur5e_ws/src git clone -b melodic-devel https://git…

llama-factory SFT 系列教程 (四),lora sft 微调后,使用vllm加速推理

文章目录 文章列表&#xff1a;背景简介llama-factory vllm API 部署融合 lora 模型权重 vllm API 部署HuggingFace API 部署推理API 部署总结 vllm 不使用 API 部署&#xff0c;直接推理数据集 tenplatevllm 代码部署 文章列表&#xff1a; llama-factory SFT系列教程 (一)&a…

【Django】调用django的pbkdf2_sha256加密算法测试

基于django搭建的系统中&#xff0c;用到pbkdf2_sha256&#xff08;&#xff08;Password-Based Key Derivation Function 2&#xff09;&#xff09;加密算法&#xff0c;这里做些代码测试、总结。 PBKDF2简介 PBKDF2是一种基于密码的密钥派生函数&#xff0c;用于从用户提供的…

cv2技术原理-图像旋转原理及手动实现

cv2技术原理-图像旋转原理及手动实现 1、图像旋转opencv实现2、cv2.getRotationMatrix2D函数解释3、数学原理推导旋转矩阵M4、手动计算旋转矩阵M5、旋转矩阵M的使用6、使用旋转矩阵M手动实现旋转功能 1、图像旋转opencv实现 图像旋转在对数据集数据增强&#xff08;主要是随机…

Spring 声明式事务控制

1. 编程式事务控制相关对象 1.1 PlatformTransactionManager PlatformTransactionManager 接口是 spring 的事务管理器&#xff0c;它提供了我们常用的操作事务的方法。 PlatformTransactionManager 是接口类型&#xff0c;不同的 Dao 层技术则有不同的实现类。例如:Dao层技…

Sileo安装插件报错:Depends mobilesubstrate

Sileo安装插件报错 iOS 15.8系统&#xff0c;使用palera1n越狱&#xff0c;然后使用Sileo安装插件的时候&#xff0c;有些插件会报错&#xff1a;Depends mobilesubstrate&#xff08;比如AppStore plus&#xff09; 报错的原因分析 从提示信息很容易可以看出&#xff0c;当…

upload-labs第十一十二关

第十一关 $is_upload false; $msg null; if(isset($_POST[submit])){$ext_arr array(jpg,png,gif);$file_ext substr($_FILES[upload_file][name],strrpos($_FILES[upload_file][name],".")1);if(in_array($file_ext,$ext_arr)){$temp_file $_FILES[upload_fil…

MySQL-进阶篇-一条sql更新语句是如何执行的(redo log和binlog)

上一篇&#xff1a;一条sql查询语句是如何执行的 http://t.csdnimg.cn/nV3EY 摘自&#xff1a;林晓斌MySQL实战45讲——第二篇 更新语句的执行过程与上一篇查询流程相同&#xff0c;本篇简写。 但多了两个重要的日志模块&#xff1a;redo log&#xff08;重做日志&#xff0…

leetcode:滑动窗口----3. 无重复字符的最长子串

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。示例 2: 输入: s "bbbbb" 输出: 1 解释: 因为…

利用穷举算法求一个整数数组A中的逆序对的个数(C语言)

目录 实验内容&#xff1a; 实验过程&#xff1a; 1.算法设计 2.程序清单 3.复杂度分析 4.实验结果 实验内容&#xff1a; 给定一个整数数组A&#xff08;a0,a1,…,an-1&#xff09;&#xff0c;若i<j且ai>aj&#xff0c;则<ai,aj>就为一个逆序对&#xff0c…

STM32电机控制SDK实战

一、前言 本次测试基于ST开发板NUCLEO-F302R8&#xff0c;驱动板X-NUCLEO-IHM07M1&#xff0c;使用无刷直流电机BLDC实现FOC控制&#xff1b;采样三霍尔传感器检测电机转子位置&#xff1b;基于速度环闭环控制实现电机转动&#xff1b; 二、实战环境 软件环境&#xff1a; 1…

布隆过滤器初探

1、什么是布隆过滤器 布隆过滤器是一个很长的二进制向量和一系列随机hash函数。布隆过滤器可以用于检索一个元素是否在一个集合中。 常见的hash函数的应用hashMap、hashSet等 回顾一下hashMap的结构 hashMap由数组链表红黑树&#xff08;java1.8后&#xff0c;链表元素长度大…

Redis入门到通关之GEO实现附近的人功能

文章目录 ☃️概述☃️命令演示☃️API将数据库表中的数据导入到redis中去☃️实现附近功能 ☃️概述 GEO就是Geolocation的简写形式&#xff0c;代表地理坐标。Redis在3.2版本中加入了对GEO的支持&#xff0c;允许存储地理坐标信息&#xff0c;帮助我们根据经纬度来检索数据。…

OpenHarmony 蓝牙相关API用法

介绍 本示例通过使用蓝牙低功耗心率服务&#xff0c;展示蓝牙相关API用法。实现了以下几点功能&#xff1a; 发现具有特定服务的设备。连接到设备。发现服务。发现服务的特征、如何读取给定特征的值、为特征设置通知等。 相关概念 BLE扫描&#xff1a;通过BLE扫描接口实现对…

【DA-CLIP】图像复原在AutoDL上部署测试

起因&#xff1a; 虽然在本机Windows部署成功运行&#xff0c;但是由于计算资源少只有6G的GPU无法计算手机拍摄图像复原和其他一些数据集测试&#xff0c;尝试租用AutoDL的服务器部署测试 租AutoDL 租的人很多&#xff0c;刚确定运行的镜像环境就报告说这个机子已经没卡了&am…

《QT实用小工具·二十八》基于qt开发的各种曲线

1、概述 源码放在文章末尾 该项目实现了各种曲线的绘制&#xff0c;下面是项目的demo演示&#xff1a; 项目部分代码如下&#xff1a; #include "frmsmoothcurve.h" #include "ui_frmsmoothcurve.h" #include "smoothcurve.h" #include "…