【基础算法总结】二分查找二

二分查找二

  • 1.山脉数组的峰顶索引
  • 2.寻找峰值
  • 3.寻找旋转排序数组中的最小值
  • 4.点名

在这里插入图片描述

点赞👍👍收藏🌟🌟关注💖💖
你的支持是对我最大的鼓励,我们一起努力吧!😃😃

1.山脉数组的峰顶索引

题目链接:852. 山脉数组的峰顶索引

题目描述:

在这里插入图片描述

题目描述的有些复杂,换成图形就是一个山峰让你找最顶点
在这里插入图片描述
算法原理:

首先我们会想到遍历,找到这个数组中第一次出现当前这个值比下一个值大的下标,

解法一:暴力枚举 O(N)

题目要求O(logn),我们看看有没有优化的地方。我们发现这个峰顶值把数组分成了两部分,这时你会想到什么 二段性
在这里插入图片描述
解法二:二分查找算法

在这里插入图片描述

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;

    }
};

2.寻找峰值

题目链接:162. 寻找峰值

题目描述:

在这里插入图片描述

这道题也是找峰值但是和上面不一样的是上面那道题数组就是上下一种情况,而这里数组可能会有三种情况:

在这里插入图片描述

算法原理:

解法一:暴力求解 O(N)
从第一个位置开始,一直往后走,分情况讨论即可

分析一下有没有优化的地方。因为我们就是比较当前位置和下一个位置的关系,所以我们把这个数组抽象出来。

在这里插入图片描述

  1. arr[i] > arr[i+1] ,此时是一个下降趋势,左边区间一定会存在一个峰值,左右都是负无穷,左边是从负无穷开始的,呈现上升趋势然后才下降,所以左边一定是有峰值的。但是右边区间不一定,因为右边是负无穷可能一直下降。接下来去左边寻找。
  2. arr[i] < arr[i+1],此时是一个上升趋势,左边是从服务器开始可能一直在上升,那可能是没有最终结果的。但是右边一定是有最终结果的,因为右边是负无穷,会降到负无穷的。接下来去右边寻找。

我们发现这两个点的关系把整个数组分成了两部分。然后我们去一个部分去搜索结果。

解法二:二分查找
这道题是严格无序的,因为可能存在一升一降、一升一降。但是我们找到了二段性,因此也可以用二分查找算法。

在这里插入图片描述

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;

    }
};

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

题目链接:153. 寻找旋转排序数组中的最小值

题目描述:

在这里插入图片描述
注意题目给的是 互不相同 的元素
在这里插入图片描述
算法原理:

这道题暴力求解很容易想到办法,从前往后遍历然后找最小值就可以了

解法一:暴力求解 O(N)

但是我们观察之后,发现这个数组可以分成两段。A-B 递增 C-D也是递增。
假设我们已D为分割点,我们发现A-B内的值大于D,C-D内的值小于等于D。由此我们发现了二段性
在这里插入图片描述

解法二:二分查找算法

在这里插入图片描述

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

上面我们以D为分割点,那以A点为分割点可不可以?其实也是可以的,但是要注意可以旋转之后是一个严格递增的数组,这里要特别处理一下。以D为分割点不会碰到这个问题。可以自己分析一波
在这里插入图片描述

class Solution {
public:
    int findMin(vector<int>& nums) {
        int left=0,right=nums.size()-1;
        int n=right;
        while(left<right)
        {
		    int mid=left+(right-left)/2;
		    if(nums[mid]>=nums[0]) left=mid+1;
		    else right=mid;
		}
         //旋转后严格单调递增
         if(nums[left]>nums[0]) return nums[0];
         return nums[left];
    }
};

4.点名

题目链接:LCR 173. 点名

题目描述:

在这里插入图片描述
算法原理:

这道题很简单,总要考察的是对于一种题你有几个解题思路

解法一:哈希表 时间O(N) 空间O(N)
把数组中所有数映射进hash表

class Solution {
public:
    int takeAttendance(vector<int>& records) {
    
    	//1.哈希表
        int n=records.size()+1;
        int hash[10001]={0};
        for(int i=0;i<records.size();++i)
        {
            hash[records[i]]++;
        }
        
        for(int i=0;i<n;++i)
        {
            if(hash[i]==0) return i;
        }
    }
};

解法二:暴力遍历 O(N)

class Solution {
public:
    int takeAttendance(vector<int>& records) {
    
    	//2.暴力遍历
        int n=0;
        for(int i=0;i<records.size();i++)
        {
            if(records[i] != n) break;
            ++n;
        }
        return n;
    }
};

解法三:位运算

将缺少的上面和不缺少的下面进行异或运算。异或运算相同为0,相异为1。最终会有正确结果。具体操作是将数字和下标异或,最后在异或一次就可以了
在这里插入图片描述

class Solution {
public:
    int takeAttendance(vector<int>& records) {
    
        //3.位运算
        int x = 0;
        for (int i = 0; i < records.size(); i++)
            x ^= records[i] ^ i ;
        return x^records.size();
    }
};

解法四:等差数列求和

class Solution {
public:
    int takeAttendance(vector<int>& records) {
    
    	//4.求和公式
        int n = records.size();
        int sum = (1+n)*n/2;
        for(int i = 0;i<records.size();++i)
        {
            sum-=records[i];
        }
        return sum;
    }
};

上面时间复杂度都是O(N),思考一下看看有没有优化的可能

在这里插入图片描述
由此发现二段性

解法五:二分查找算法
在这里插入图片描述

class Solution {
public:
    int takeAttendance(vector<int>& records) {

        //0.二分查找
        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;
        }
        if(left == records[left]) return left+1;
        else return left;
    }
};

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

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

相关文章

【vue3】vue3中如何使用typescript

简言 现在vue3和typescript搭配使用是一个较常见的方案&#xff0c;下面参考vue3官网总结下在vue项目中使用ts(TypeScript)的方法。 typescript配置 新建项目 如果你准备新建vue3项目&#xff0c;那么使用create-vue官方脚手架&#xff0c;它提供了搭建基于 Vite 且 TypeSc…

vue-pure-admin项目内复制文字粘贴到word中之后存在边框问题

vue-pure-admin项目内复制文字粘贴到word中之后存在黑色边框是由于reset.scss文件内设置了通配符的border样式 修改前 代码 *, ::before, ::after {box-sizing: border-box;// 添加这个样式会导致复制的文字粘贴到word中带有边框问题border-color: currentColor;border-styl…

CCF PTA 2022年11月C++学生会提名

【问题描述】 学生会选举要开始了。根据选举规则&#xff0c;首先由全体同学进行提名&#xff0c;每位同学可以从全体同学中提 名一名同学参选。选举时&#xff0c;会从全体同学的提名中选出一名学生会主席&#xff0c;再从三个年级分别的提名中 各选出一名副主席。现在&#…

sa-token权限认证框架,最简洁,最实用讲解

查看源码&#xff0c;可知&#xff0c;sa sa-token框架 测试代码源码配置自动装配SaTokenConfigSaTokenConfigFactory SaManager工具类SaFoxUtilStpUtilSaResult StpLogic持久层定时任务 会话登录生成token创建account-session事件驱动模型写入tokenSaSessionSaCookieSaTokenDa…

elementui,iview等 表格单元格合并之固定列

要的效果如下 需要合并 show weak 及 Siginin这三列 上代码 <template><Table:columns"columns":span-method"handleSpan":data"data"bordersize"small"ref"table"></Table> </template> <sc…

Linux备份---异地

参考文档&#xff1a;Linux环境实现mysql所在服务器定时同步数据文件到备份服务器&#xff08;异地容灾备份场景&#xff09;_mysql异地备份-CSDN博客 通过SSH进行连接&#xff1a; 应用服务器&#xff1a; 通过ssh-keygen -t rsay建立ssh通信的密钥 密钥建立后&#xff0c;…

JavaScript-输入输出语句

输出语句 document.write( 输出的内容 ) 语法&#xff1a;document.write( 输出的内容) 作用&#xff1a;内容会显示在网页上 如果输出的内容是标签&#xff0c;也会被解析为网页元素 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head>&…

cubemx配置stm32f407VET6实现can通信

背景&#xff1a; 项目上需要把原先的TMC5160电机驱动器替换为购买的电机控制模块&#xff08;该模块采用canopen通信&#xff09; 移植canopen的前提是can通信正常&#xff0c;现在添加一下can通信&#xff08;先用标准帧&#xff0c;250K bit/S的波特率测试&#xff09; 原理…

【回溯】1255. 得分最高的单词集合

本文涉及知识点 回溯 力扣难道&#xff1a;1881 LeetCode1255. 得分最高的单词集合 你将会得到一份单词表 words&#xff0c;一个字母表 letters &#xff08;可能会有重复字母&#xff09;&#xff0c;以及每个字母对应的得分情况表 score。 请你帮忙计算玩家在单词拼写游戏…

系统管理(System Keeping):Codigger资源与配置管理(上)

系统管理&#xff08;System Keeping&#xff09;&#xff0c;作为Codigger不可或缺的一部分&#xff0c;为开发者提供全面而高效的资源与配置管理体验。下面&#xff0c;让我们从它的其中三方面来一探究竟其强大的功能如何助力开发者提升工作效率。 一、环境配置&#xff1a;全…

Linux交叉编译

一. 交叉编译 1.使用环境要求 新版本的orangepi-build是在Ubuntu22.04的x64电脑或虚拟机上运行的 lsb_release -a //查看自己的虚拟机版本 因为编译出的SDK大概有16G大小&#xff0c;因此&#xff0c;至少给虚拟机分配50G的大小。 2.获取Linux SDK 方法一&#xff1a;从…

React框架-Next 学习-1

创建一个 Next.js 应用,node版本要高&#xff0c;16.5以上 npm淘宝镜像切为https://registry.npmmirror.com npm config set registry https://registry.npmmirror.com npx create-next-applatest//安装后 使用npm run dev 启动 Next.js 是围绕着 页面&#xff08;pages&am…

智慧园区EasyCVR视频智能管理方案:构建高效安全园区新视界

一、背景分析 园区作为城市的基本单元&#xff0c;是最重要的人口和产业聚集区。根据行业市场调研&#xff0c;90%以上城市居民工作与生活在园区进行&#xff0c;80%以上的GDP和90%以上的创新在园区内产生&#xff0c;可以说“城市&#xff0c;除了马路都是园区”。 园区形态…

高通QCS6490开发(二)AI板卡接口

QCS6490是高通公司针对高端物联网终端而优化的SoC&#xff0c;在性能和功耗上有最优的平衡。《高通QCS6490 AIoT应用开发》是一系列AIoT应用开发文章&#xff0c;介绍如何基于QCS6490平台做AIIoT的应用开发。 本文主要介绍FV01开发板的内部和外部接口。 内部的板载接口如下 接口…

怎么做私域?先来了解私域运营模式!

现在&#xff0c;很多企业都在做私域&#xff0c;但仍旧有很多人会问&#xff1a;我的私域到底要怎么做&#xff1f; 关于这个问题&#xff0c;不同产品无论在消费频次与客单价上&#xff0c;还是在决策链路的长度和复杂度上&#xff0c;都有巨大的差异&#xff0c;消费者需要…

GPT-4o模型介绍和使用方法

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

java项目之企业资产管理系统(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的企业资产管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 管理员功能有个人中心&…

程序员兼职引起的纠纷?

最近跟朋友聊天&#xff0c;说遇到一些因兼职工作而引发的争议&#xff0c;因为我本人也曾涉足过兼职领域&#xff0c;因此对程序员兼职时可能遇到的各种情况和应遵循的“套路”准则还有有一些发言权的&#xff0c;所以想和大家聊聊如何安全“兼职”的1/2事项~ ✅顺便内推个机会…

前端面试题(二十三)(答案版)

面试形式&#xff1a;线上电话面试&#xff1a;一面&#xff1a;时长30分钟 面试评价&#xff1a;精准考察项目所需技术理论工作实践 面试官的提问大纲&#xff1a;本公司项目要求本人简历 工作经验&#xff1a;2-4年 公司名称&#xff1a;深圳XX&#xff08;想知道的就滴喔…

SHELL编程(一)

目录 一、 Linux操作系统&#xff08;一&#xff09;内核与操作系统&#xff08;二&#xff09;操作系统的功能 二、Linux高级命令&#xff08;一&#xff09; 离线安装 dpkg1. 安装2. 使用3. 查看安装详细信息4. 安装路径5. 不完全删除6. 完全删除 &#xff08;二&#xff09;…