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

news2024/9/22 13:29:17

二分查找二

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

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

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

相关文章

Blender雕刻建模_笔刷纹理和顶点绘制

笔刷纹理 主要用于皮肤&#xff0c;纹理的雕刻。 可以修改映射方式来实现不同绘制效果。 用一张纹理来定义笔刷各个点的强度。其中白色为1&#xff0c;黑色为0。 设置笔刷纹理步骤&#xff1a; -新建一套笔刷 -强度&#xff0c;设为0.15&#xff08;可以根据需求修改&#x…

Ubuntu 配置Samba

Ubuntu 配置&#xff1a; 安装 Samba &#xff1a; sudo apt-get install samba添加用户并设置密码&#xff08;可与ubuntu用户密码相同方便记忆&#xff09; sudo smbpasswd -a root这里我设置的密码为123456 sudo vi /etc/samba/smb.conf注意这个共享的目录一定要存在\ho…

高通Android 11/12/13 通过包名设置默认launcher

背景&#xff1a;最近在封装供第三应用系统SDK 接口&#xff0c;遇到一个无法通过包名设置主launcher代码坑所以记录下。 涉及类roles.xml # <!---~ see com.android.settings.applications.defaultapps.DefaultHomePreferenceController~ see com.android.settings.appl…

git常用命令及其ignore文件

1.git本地操作命令 # 查看git的版本 git --version # 生成空的本地仓库 git init # 将文件添加到暂存区 git add 文件 # 将暂存区里的文件提交到本地仓库 git commit -m "描述"2.git远程仓库命令 # 添加远程仓库 git remote add origin http://192.168.1.130:9000/…

asp.net 齿轮加工车间生产管理系统-计算机毕业设计源码56014

摘 要 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;在现实运用中&#xff0c;为方便用户能够可以随时进行在线…

IT Tools

ChatGpt chatGpt chatgpt vs & vscode工具 Vs Extensions & Remote Development Vs Extensions Remote-SSH VSCode远程连接到Linux并实现免密码登录 Git Graph C cppreference.com cplusplus 镜像站点 用于下载 QT, Ubuntu, 清华镜像站点 CMake Downlo…

C语言详解:数组指针

数组指针是指针 int* p[10] 这是指针数组的写法 &#xff0c;因为【】的优先级比*高&#xff0c; 所以为了解决优先级问题&#xff0c;加&#xff08;&#xff09; int(* p)[10]&arr;//数组的地址要存起来 说明p是指针&#xff08;首先与*结合&#xff09;&#xff0c…

接口自动化-requests库

requests库是用来发送请求的库&#xff0c;本篇用来讲解requests库的基本使用。 1.安装requests库 pip install requests 2.requests库底层方法的调用逻辑 &#xff08;1&#xff09;get / post / put / delete 四种方法底层调用 request方法 注意&#xff1a;data和json都…

网络安全产业的现在时和将来时

由于之前新冠疫情在全球肆虐&#xff0c;网络安全行业面临着不少挑战。例如&#xff0c;企业在被迫数字转型过程中&#xff0c;造成数据泄露威胁加剧。另一方面&#xff0c;攻击者的攻击手段和方式也日趋复杂和成熟&#xff0c;加密勒索和针对新冠疫情的网络钓鱼层出不穷。 基…

玩转Matlab-Simscape(初级)- 06 - 基于Solidworks、Matlab Simulink、COMSOL的协同仿真(理论部分2)

** 玩转Matlab-Simscape&#xff08;初级&#xff09;- 06 - 基于Solidworks、Matlab Simulink、COMSOL的协同仿真&#xff08;理论部分2&#xff09; ** 目录 玩转Matlab-Simscape&#xff08;初级&#xff09;- 06 - 基于Solidworks、Matlab Simulink、COMSOL的协同仿真&am…

togaf培训简介2

1.定义 2.ADM 业务下降期不要瞎折腾&#xff0c;上升期配合业务做一些改革&#xff1f; 项目交付物不能是聊天记录、PPT什么的&#xff0c;最起码是邮件。 3.架构内容框架 或者叫&#xff1a;企业统一体。 包括&#xff1a;企业连续性和解决方案连续性 方案和工具的解耦很大程…

FPGA - GTX收发器-K码 以及 IBERT IP核使用

一&#xff0c;前言 在FPGA - Xilinx系列高速收发器---GTX中详细介绍了GTX的基础知识&#xff0c;以及IP核的调用&#xff0c;下面将补充一下GTX在使用中的高速串行数据流在接收和发送时的控制与对齐&#xff08;K码&#xff09;&#xff0c;以及高速接口GTX&#xff0c;如果G…

CRMEB开源打通版/标准版v4电商商城系统小程序发布之后无法生成海报问题

小程序产品分销二维码生成不了 开发者工具可以生成海报&#xff0c;但是发布之后无法生成 1.在开发者工具中&#xff0c;将不校验合法域名关闭 2.点击生成海报&#xff0c;查看console 3.将域名填写到微信公众平台小程序的download合法域名中 网址微信公众平台

如何利用R包进行主成分分析和可视化

一. 使用R包“FactoMineR”进行主成分分析&#xff08;PCA&#xff09; 基本步骤如下&#xff1a; 安装和加载包&#xff1a;如果尚未安装&#xff0c;首先安装“FactoMineR”包&#xff0c;然后加载它&#xff1a; install.packages("FactoMineR")library(FactoM…

记录一下自己的宏碁暗影骑士电脑的属性

TOC 前言 没有前言。 参考博文 怎么查自己电脑服务器信息吗,如何查看自己电脑的服务器 一、cmd 看到服务器型号 wmic csproduct get name查询CPU个数 按照博主的方法&#xff0c;我出现了报错。 在 Windows 上&#xff0c;您可以通过 PowerShell 来执行类似的操作。您可以…

记一次洛谷刷题让人摸不到头脑的报错——Runtime Error.Received signal 6: Aborted / IOT trap.

报错题目 外星密码 - 洛谷 具体报错信息 Runtime Error.Received signal 6: Aborted / IOT trap. 错误代码 #include <iostream> #include <cstring> using namespace std;string sol() {string s "";string t "";char c ;int n 0;whi…

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

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

怎么将视频转成图片?看看这个网站

在日常生活中我们常常会在一些特定的场合下想要将一些视频中某个场合瞬间提取出来做成动态图片。Gif动图作为我们日常生活、工作必不可少的&#xff0c;想要通过自己制作这种有动态效果的图片就可以用gif动画制作网站&#xff0c;不用下载软件&#xff0c;手机、pc都可以在线操…

使用Python批量复制文件夹及其子文件夹下的指定文件

目录 一、引言 二、Python文件操作基础 三、复制文件夹及其子文件夹下的指定文件 四、案例分析 五、注意事项与扩展 六、结论 一、引言 在数据处理和文件管理的日常工作中&#xff0c;我们经常需要复制文件夹及其子文件夹下的特定文件。手动操作不仅效率低下&#xff0c…

2024年网络安全威胁

随着2024年的到来&#xff0c;数字世界的版图正在以前所未有的速度扩张&#xff0c;引领我们进入一个技术革新的新时代。然而&#xff0c;这飞速的发展同时也催生了一系列错综复杂的网络安全挑战。在这个数字平台与我们生活日益紧密交织的时代&#xff0c;深入了解这些新兴的威…