力扣基础刷题---二分查找

704. 二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1

中心思想:找到中间值,跟中间值比较,如果比中间的大,就在后半部分;如果比中间的小,就在前半部分;如果相等即为所求。当遍历到最后,还不存在,则说明不存在。

方法一:左闭右闭区间( right=nums.size()-1;)

target 是在一个在左闭右闭的区间里,也就是[left, right] ,在这个情况下,while要包含left==right的情况。

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

方法二:左闭右开区间( right=nums.size();)

  • while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的
  • if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left=0;int right=nums.size();
        if(right<=left) return -1;
        while(left<right){
            int mid=(right+left)/2;
            if(nums[mid]==target)   return mid; 
            else if(nums[mid]<target) left=mid+1;
            else right=mid;   
        }
        return -1;
    }
};

374. 猜数字大小

这道题读懂题目即可。其实和上面一模一样

需要注意:

  • 1 <= n <= 2^{31} - 1
  • 2n其实超出了int的范围,所以需要把left、right、mid设置为long 类型
class Solution {
public:
    int guessNumber(int n) {//左闭右闭区间
        long left=1;long right=n;long mid;
        while(left<=right){
            mid=(left+right)/2;
            if(guess(mid)>0)// pick > num
                left=mid+1;
            else if(guess(mid)==0) break;
            else right=mid-1;
        }
        return mid;
    }
};

35. 搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 

时间复杂度为 O(log n) 的算法。-----》二分算法

返回按顺序插入的位置,其实就是二分查找的时候,left所在的点。

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

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

两个方法:简单点想其实就是找到所有与target相等的值,最小的就是第一个,最大的就是最后一个。全部找出来,复杂度有点高。

方法一:那不妨想,第一个实际上就是不断向前找;最后一个就是不断向前找。可以分为两次查找 

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        if(!nums.size()) return {-1,-1};
        int first=-1;int last=-1;int mid;
        int left=0;int right=nums.size()-1;
        //找first
        while(left<=right){
            mid=(left+right)/2;
            if(nums[mid]==target) {
                first=mid;
                right=mid-1;//不断向前找
            }
            else if(nums[mid]>target) right=mid-1;
            else left=mid+1;
        }
        
        //找last
        left=0; right=nums.size()-1;
        while(left<=right){
            mid=(left+right)/2;
            if(nums[mid]==target) {
                last=mid;
                left=mid+1;//不断向后找
            }
            else if(nums[mid]>target) right=mid-1;
            else left=mid+1;
        }

        return {first,last};
    }
};

方法二:看上面的代码,其实大部分代码都是相同的逻辑,我们不防精简一下:

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int l = 0, r = nums.size() - 1;
        vector<int> ret {-1, -1};
        while(l <= r){
            int mid = (l + r) / 2;
            if(nums[mid] > target){
                r = mid - 1;
            }else if (nums[mid] < target){
                l = mid + 1;
            }else{
                l = r = mid;
                while(--l >= 0 && nums[l] == target){
                    ;
                }
                while(++r < nums.size() &&nums[r] == target){
                    ;
                }
                ret[0] = l + 1;
                ret[1] = r - 1;
                return ret;
            }
        }
        return ret;
    }
};

这个就是找到中间那个相等的值之后,不断像前,向后逼近。(一次二分)

                while(--l >= 0 && nums[l] == target){
                    ;
                }
                while(++r < nums.size() &&nums[r] == target){
                    ;
                }
                ret[0] = l + 1;
                ret[1] = r - 1;

167. 两数之和 II - 输入有序数组

双指针+空间缩减(题解推荐:167. 两数之和 II - 输入有序数组 - 力扣(LeetCode))

同样这里注意审题,返回的下标

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {//双指针+缩减空间
        int row=0;int col=numbers.size()-1;
        
        while(row<col){
            int sum=numbers[row]+numbers[col];
            if(sum>target){
                col--;
            }
            else if(sum<target) row++;
            else return vector<int>{row+1,col+1};
        }
        return vector<int>{-1,-1};
    }
};

拓展一下:返回二维数组的情况还可以直接返回

{row+1,col+1};

或者利用veror动态数组的内置函数

        vector<int> res;
                res.push_back(low+1);
                res.push_back(high+1);
        return res;

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

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

相关文章

PCIE1—快速实现PCIE接口上下位机通信(一)

1.简介 PCI Express&#xff08;PCIE&#xff09;是一种高速串行总线标准&#xff0c;广泛应用于计算机系统中&#xff0c;用于连接主板和外部设备。在FPGA领域中&#xff0c;PCIE也被广泛应用于实现高速数据传输和通信。FPGA是一种灵活可编程的集成电路&#xff0c;可以根据需…

时序数据库TimescaleDB,实战部署全攻略

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

bat 查找文件所在

脚本 在批处理文件&#xff08;.bat&#xff09;中查找文件所在的目录&#xff0c;你可以使用dir命令结合循环和条件语句来实现。以下是一个简单的示例&#xff0c;演示如何在批处理文件中查找指定文件并输出其所在目录&#xff1a; echo off setlocal enabledelayedexpansio…

绩效域-错题笔记

1、虚荣指标&#xff1a;对决策没有帮助的度量指标一般属于虚荣指标。 例如&#xff1a;新访问者的数量比网站的页面访问量更加有用。 2、完工偏差(VAC)用于预测预算赤字或盈余金额&#xff0c;它表示为完工预算(BAC)和完工估算(EAC)之差。 3、完工尚需绩效指数(TCPI)用于估…

pikachu靶场-CSRF

CSRF: 介绍&#xff1a; Cross-site request forgery简称为"CSRF”。 在CSF的攻击场景中攻击者会伪造一个请求&#xff08;这个请求一般是一个链接&#xff09; 然后欺骗目标用户进行点击&#xff0c;用户一旦点击了这个请求&#xff0c;整个攻击也就完成了&#xff0…

Java毕业设计-基于ssm的校园二手交易管理系统-第67期

获取源码资料&#xff0c;请移步从戎源码网&#xff1a;从戎源码网_专业的计算机毕业设计网站 项目介绍 基于ssm的校园二手交易管理系统&#xff1a;前端jsp、jquery&#xff0c;后端 springmvc、spring、mybatis&#xff0c;集成商品管理、订单管理、销售管理、采购管理、购…

phaseDNN文章解读

文章DOI: https://doi.org/10.48550/arXiv.1905.01389 作者是 Southern Methodist University 的Wei Cai 教授 A Parallel Phase Shift Deep Neural Network for Adaptive Wideband Learning 一种并行移相深度神经网络来自适应学习宽带频率信号 20190514 核心思想&#xff1a;…

客户端web开发工具

文章目录 安全网络Linter-->捕获代码错误-->eslint源代码控制-->Git代码格式化-->Prettier打包工具--Parcel--Webpack 转换--Babel开发后阶段测试工具配置工具其他 node&#xff0c;npm、yarnnode.js包管理器npmyarn https://developer.mozilla.org/zh-CN/docs/Lea…

RM电控讲义【HAL库篇】

这段代码中do while的作用&#xff1a; 宏定义中的语句块&#xff1a;do { ... } while (0) 允许你在宏定义中创建一个语句块&#xff0c;从而可以包含多条语句。这在宏定义中特别有用&#xff0c;因为宏只是简单的文本替换&#xff0c;不像函数那样有作用域和返回类型。因此&…

Docker基础篇(-)

docker 三个要素 镜像容器仓库 CentOS 6.8 安装 docker centos 7.0 yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager -y --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo systemctl start docker 启动Docker&…

嵌入式中c语言指针用法详解与分析

今天给大家来讲解一下指针。 我会由浅到深&#xff0c;最后结合实际应用讲解&#xff0c;让大家学会指针的同时&#xff0c;知道大佬们都用指针来干嘛&#xff01; 长文预警&#xff01;全文大约5200多字&#xff0c;学指针看这篇文章就够了&#xff01; 很多人跟我刚学习c语…

electorn+vue3项目启动后报错unsafe-eval,如何去除提醒

electron项目报错如下&#xff1a; Electron Security Warning (Insecure Content-Security-Policy) This renderer process has either no Content Security Policy set or a policy with “unsafe-eval” enabled. This exposes users of this app to unnecessary security r…

【FreeRTOS基础入门】任务通知

文章目录 前言一、任务通知介绍1.1 任务通知怎么通信1.2 任务通知与其他通信方式的区别1.3 优势及限制任务通知的优势任务通知的限制 1.4 内部原理 二、任务通知的使用2.1 发出与接收通知简化版2.1 发出与接收通知专业版 总结 前言 FreeRTOS 提供了丰富而灵活的任务通知机制&a…

基于51单片机的婴儿看护监测系统[proteus仿真]

基于51单片机的婴儿看护监测系统[proteus仿真] 婴儿看护检测系统这个题目算是课程设计和毕业设计中少见的题目&#xff0c;本期是一个基于51单片机的婴儿看护监测系统[proteus仿真] 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】&#xff0c;赞赏任意文章 2&a…

openGauss学习笔记-226 openGauss性能调优-系统调优-配置LLVM-LLVM适用场景与限制

文章目录 openGauss学习笔记-226 openGauss性能调优-系统调优-配置LLVM-LLVM适用场景与限制226.1 适用场景226.2 非适用场景 openGauss学习笔记-226 openGauss性能调优-系统调优-配置LLVM-LLVM适用场景与限制 226.1 适用场景 支持LLVM的表达式 查询语句中存在以下的表达式支持…

优化设备维修流程:易点易动设备管理系统的设备维修管理策略

在现代企业中&#xff0c;设备是生产运营的核心要素之一。然而&#xff0c;设备故障和维修常常给企业带来诸多困扰和成本。为了提高设备维修的效率和质量&#xff0c;许多企业开始采用先进的设备管理系统。在这方面&#xff0c;易点易动设备管理系统以其卓越的设备维修管理策略…

2023年Q4,SSD出货量下降5%,但存储容量增长9.6%

2023年第四季度&#xff08;4Q23&#xff09;的SSD市场表现呈现出单位出货量下降&#xff0c;但存储容量增长的趋势。具体数据显示&#xff0c;该季度SSD总出货量下降5%&#xff0c;降至8820万台&#xff1b; 而存储容量则增长9.6%&#xff0c;达到85.1EB。预计2023全年SSD总容…

前端基于Verdaccio搭建私有npm仓库,上传npm插件包,及下载使用自己的npm插件包

文章目录 一、原理二、常用的仓库地址三、优势四、准备环境六、使用verdaccio搭建私有npm服务1、安装2、运行3、配置config.yaml&#xff0c;使局域网下能共享访问&#xff0c;否则只能本机访问。4、重新运行 七、npm常见操作查看当前用户信息查看源地址切换源地址删除源地址创…

【Linux】Linux调试器-gdb使用

1. 背景 程序的发布方式有两种&#xff0c;debug模式和release模式 Linux gcc/g出来的二进制程序&#xff0c;默认是release模式 要使用gdb调试&#xff0c;必须在源代码生成二进制程序的时候, 加上 -g 选项 2. 开始使用 gdb binFile 退出&#xff1a; ctrl d 或 quit 调…

【C语言】注释

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;C语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&…