【算法】二分算法题

个人主页 : zxctscl
如有转载请先通知

题目

  • 1. 704. 二分查找
    • 1.1 分析
    • 1.2 代码
  • 2. 34. 在排序数组中查找元素的第一个和最后一个位置
    • 2.1 分析
    • 2.2 代码
  • 3. 35. 搜索插入位置
    • 3.1 分析
    • 3.2 代码
  • 4. 852. 山脉数组的峰顶索引
    • 4.1 分析
    • 4.2 代码
  • 5. 153. 寻找旋转排序数组中的最小值
    • 5.1 分析
    • 5.2 代码
  • 6. 二分算法模板

1. 704. 二分查找

在这里插入图片描述

1.1 分析

用两个指针,一个在前面left,一个在后面right,求出中间值half,与目标值比较。如果相等,就直接返回下标;如果小于目标值,说明值在后面的区间,此时更新一下left=half+1;如果如果大于目标值,说明值在前面的区间,此时更新一下right=half-1。如果区间都找完没有,就返回-1。
在这里插入图片描述

1.2 代码

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

2. 34. 在排序数组中查找元素的第一个和最后一个位置

在这里插入图片描述

2.1 分析

寻找左边界:
我们注意到以左边界划分的两个区间的特点:
左边区间 [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 == 2mid == 2 。更新区间之后, left,right,mid 的值没有改变,就会陷入死循环)。因此⼀定要注意,当 right = mid 的时候,要向下取整。

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

在这里插入图片描述

2.2 代码

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target)
    {
        if (nums.size() == 0) return { -1, -1 };

        int begin = 0;
        // 1. ⼆分左端点
        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 { -1, -1 };
        else begin = left; // 标记⼀下左端点
        // 2. ⼆分右端点
        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 };
    }

};

3. 35. 搜索插入位置

在这里插入图片描述

3.1 分析

利用二分算法的特性,将区间分为两部分,一部分是小于目标值的,那么这个区间就不考虑了;另一部分是等于等于目标值的,如果等于目标值那么就直接返回这个下标,如果大于目标值,那么这个值也是第一个比目标值大的数,这个位置的数之前就得插入目标值,返回的也是这个下标。
在这里插入图片描述

在这里插入图片描述

3.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 right + 1;
    return left;
    }
};

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

在这里插入图片描述

4.1 分析

题目给的元素特性很明显,在某一个位置之前的元素都是呈现上升趋势,在它之后都会呈现下降趋势。按照这个特性可以将数组分为两部分:1.mid的值小于mid-1,那么最大值就在前面的区间,那么就更新一下right=mid-1;2.mid的值大于等于mid-1,那么最大值就在后面的区间,更新一下left=mid。最终就找到当循环条件返回left就可以。
在这里插入图片描述

在这里插入图片描述

4.2 代码

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

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

在这里插入图片描述

5.1 分析

根据题目所给的特性,可以将数组分为两段区间,都是明显呈现递增。第二段区间所有的值都小于第一段。选择最后最后一个值为参考值。如果在mid大于最后一个值,说明最小值在后面的区间,更新一下left=mid+1;如果如果在mid小于等于最后一个值,那么就更新一下right=mid。
在这里插入图片描述

在这里插入图片描述

5.2 代码

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

6. 二分算法模板

定义两个指针,然后找符合条件的情况按下面的模板走。
填上对应的if表达式,返回题目要求的值即可。
在这里插入图片描述

有问题请指出,大家一起进步!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TiDB 实战分享丨第三方支付企业的核心数据库升级之路

本文介绍了一家第三方支付企业在面对市场竞争和监管压力的态势下&#xff0c;通过升级核心数据库来提升业务能力的实践。该企业选择 TiDB 分布式数据库&#xff0c;成功将其应用于核心业务、计费、清结算和交易查询等关键系统。TiDB 的水平扩展能力、高可用性和简化数据栈等优势…

异常的种类

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 Oracle 运行时错误可以分为 Oracle 错误和用户自定义错误&#xff0c;与此对应&#xff0c;根据异常产生的机制和原理&#xff0c;可将 Oracle 的系统异常分为 3 种 预定义…

MySQL事务以及并发访问隔离级别

MySQL事务以及并发问题 事务1.什么是事务2.MySQL如何开启事务3.事务提交方式4.事务原理5.事务的四大特性&#xff08;ACID&#xff09; 事务并发问题1.并发引起的三个问题2.事务隔离级别 事务 在 MySQL 中&#xff0c;事务支持是在引擎层实现的。MySQL 是一个支持多引擎的系统&…

猫头虎博主分享运维技巧: 解决RuntimeError: Expected all tensors to be on the same device

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

Java基于SpringBoot+Vue的专家医院预约挂号系统,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

【C++航海王:追寻罗杰的编程之路】探寻实用的调试技巧

目录 1 -> 什么是bug&#xff1f; 2 -> 调试是什么&#xff1f;有多重要&#xff1f; 2.1 -> 调试是什么&#xff1f; 2.2 -> 调试的基本步骤 2.3 -> Debug和Release的介绍 3 -> Windows环境调试介绍 3.1 -> 调试环境的准备 3.2 -> 学会快捷键…

7-17 爬动的蠕虫

题目链接&#xff1a;7-17 爬动的蠕虫 一. 题目 1. 题目 2. 输入输出样例 3. 限制 二、代码 1. 代码实现 #include <stdio.h>int main(void) {unsigned int n, u, d;unsigned int minute, high;if (scanf("%d %d %d", &n, &u, &d) ! 3) {retur…

【CKA模拟题】边车容器Shared-Volume的具体用法

Useful Resources: Persistent Volumes Claim , Pod to Use a PV 题干 For this question, please set this context (In exam, diff cluster name) kubectl config use-context kubernetes-adminkubernetes An existing nginx pod, my-pod-cka and Persistent Volume Claim…

GIF在线生成器

上传图片就能生成GIF的前端WEB工具 源码也非常简单 <!DOCTYPE html> <html lang"zh" class"dark"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1, m…

设计模式学习笔记 - 设计模式与范式 -行为型:8.状态模式:游戏、工作流引擎中常用的状态机是如何实现的?

概述 本章学习状态模式。在实际的开发中&#xff0c;状态模式并不是很常用&#xff0c;但是在能够用到的场景里&#xff0c;它可以发挥很大的作用。从这一点上看&#xff0c;它有点像我们之前讲到的组合模式。 状态模式一般用来实现状态机&#xff0c;而状态机常用在游戏、工…

前端三剑客 —— JavaScript (第一节)

目录 回顾内容 1.弹性布局 2.网格布局 JavaScript 概述 发展 浏览器 什么是Javascript JavaScript 能干什么 JavaScript需要的环境 JavaScript初体验 基本数据 JS书写方式 行内JS 页面JS 外部JS 1&#xff09;创建外部JS文件 2&#xff09;编写页面 对话框 警…

类的函数成员(四):赋值函数

一.赋值函数是什么&#xff1f; 1.1 运算符的重载 运算符的重载实际是一种特殊的函数重载&#xff0c;必须定义一个函数&#xff0c;并告诉C编译器&#xff0c;当遇到该重载的运算符时调用此函数。这个函数叫做运算符重载函数&#xff0c;它通常为类的成员函数。 定义运算符重…

TCP 重传、滑动窗口、流量控制、拥塞控制(计算机网络)

重传机制 TCP 针对数据包丢失的情况&#xff0c;会用重传机制解决。 接下来说说常见的重传机制&#xff1a; 超时重传快速重传SACKD-SACK 超时重传 重传机制的其中一个方式&#xff0c;就是在发送数据时&#xff0c;设定一个定时器&#xff0c;当超过指定的时间后&#xff0c…

HarmonyOS实战开发-如何使用 geolocation 实现获取当前位置经纬度

介绍 本示例使用 geolocation 实现获取当前位置的经纬度,然后通过 http 将经纬度作为请求参数,获取到该经纬度所在的城市。通过 AlphabetIndexer 容器组件实现按逻辑结构快速定位容器显示区域。 效果预览 使用说明 1.进入主页,点击国内热门城市,配送地址会更新为选择的城…

javaScript 事件循环 Event Loop

一、前言 javaScript 是单线程的编程语言&#xff0c;只能同一时间内做一件事情&#xff0c;按照顺序来处理事件&#xff0c;但是在遇到异步事件的时候&#xff0c;js线程并没有阻塞&#xff0c;还会继续执行&#xff0c;这又是为什么呢&#xff1f; 二、基础知识 堆&#x…

vivado HDL 例化调试探测流程概述

HDL 例化调试探测流程概述 HDL 例化探测流程涉及在 HDL 设计源代码中直接手动自定义、例化和连接各种调试核组件。下表中显示了 Vivado 工具中此流程所支持的新调试核。 新的 ILA 核相比于传统 ILA v1.x 核具有以下 2 大优势 &#xff1a; • 可搭配集成的 Vivado Log…

FreeRTOS临界段代码保护和任务调度器的挂起与恢复学习

FreeRTOS临界段代码保护和任务调度器的挂起与恢复学习 临界段代码保护 所谓临界段代码保护就是指必须完成运行&#xff0c;不能被打断的代码段。比如需要严格按照时序除初始化的外设&#xff1a;IIC、SPI&#xff0c;再或者因为系统自身需求和用户需求。 FreeRTOS 在进入临界…

发型不满意试试开源AI换发型HairFastGAN;前OpenAI员工Karpathy1000纯C语言写完GPT-2

✨ 1: HairFastGAN 开源AI换发型 HairFastGAN 是一种先进的技术&#xff0c;专门设计用于在不同图片之间传输发型。这意味着如果你有一张人物的图片和另一张你喜欢的发型的图片&#xff0c;HairFastGAN 能够将你喜欢的那个发型复制到人物的头上&#xff0c;而且看起来非常自然…

强化学习MPC——(二)

本篇主要介绍马尔科夫决策&#xff08;MDP&#xff09;过程&#xff0c;在介绍MDP之前&#xff0c;还需要对MP&#xff0c;MRP过程进行分析。 什么是马尔科夫&#xff0c;说白了就是带遗忘性质&#xff0c;下一个状态S_t1仅与当前状态有关&#xff0c;而与之前的状态无关。 为…

深入浅出索引(上)

提到数据库索引&#xff0c;我想你并不陌生&#xff0c;在日常工作中会经常接触到。比如某一个 SQL 查询比较慢&#xff0c;分析完原因之后&#xff0c;你可能就会说“给某个字段加个索引吧”之类的解决方案。但到底什么是索引&#xff0c;索引又是如何工作的呢&#xff1f;今天…