二分查找——经典题目合集

在这里插入图片描述

文章目录

    • 🦜69. x 的平方根
      • 🌼题目
      • 🌻算法原理
      • 🌷代码实现
    • 🐳35. 搜索插入位置
      • 🌼题目
      • 🌻算法原理
      • 🌷代码实现
    • 🦭852. 山脉数组的峰顶索引
      • 🌼题目
      • 🌻算法原理
      • 代码实现
    • 🐧162. 寻找峰值
      • 🌼题目
      • 🌻算法原理
      • 🌷代码实现
    • 🦚153. 寻找旋转排序数组中的最小值
      • 🌼题目
      • 🌻算法原理
      • 🌷代码实现
    • 🦖LCR 173. 点名
      • 🌼题目
      • 🌻算法原理
      • 🌷代码实现

704.二分查找、34. 在排序数组中查找元素的第一个和最后一个位置(二分查找模板)

🦜69. x 的平方根

🌼题目

题目链接:69. x 的平方根 - 力扣(LeetCode)

给你一个非负整数 x ,计算并返回 x算术平方根

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

注意: 不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5

示例 1:

输入:x = 4
输出:2

示例 2:

输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。

提示:

  • 0 <= x <= 231 - 1

🌻算法原理

本题采用二分查找,题目给的x,要求是有符合的平方根就返回该x的平方根,如果没有则返回小于它的整数平方根

image-20231121140246983

🌷代码实现

class Solution {
public:int mySqrt(int x) {if(x<1) return 0;	//处理边界int left = 1;int right = x;while(left<right){long long mid = left+(right-left+1)/2;	//long long防止溢出if(mid*mid <= x)    left = mid;else    right = mid-1;}return left;}
};

🐳35. 搜索插入位置

🌼题目

题目链接:35. 搜索插入位置 - 力扣(LeetCode)

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

请必须使用时间复杂度为O(log n)的算法。

示例 1:

输入: nums = [1,3,5,6], target = 5
输出: 2

示例 2:

输入: nums = [1,3,5,6], target = 2
输出: 1

示例 3:

输入: nums = [1,3,5,6], target = 7
输出: 4 

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums无重复元素升序 排列数组
  • -104 <= target <= 104

🌻算法原理

本题要求是如果找到目标值,则返回下标;如果找不到,则返回要填入的位置

image-20231121142757470

🌷代码实现

class Solution {
public:int searchInsert(vector<int>& nums, int target) {int left = 0;int 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 left+1;return left;}
};

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

🌼题目

题目链接:852. 山脉数组的峰顶索引 - 力扣(LeetCode)

符合下列属性的数组 arr 称为 山脉数组

  • arr.length >= 3
  • 存在i0 < i < arr.length - 1)使得:
    • arr[0] < arr[1] < ... arr[i-1] < arr[i]
    • arr[i] > arr[i+1] > ... > arr[arr.length - 1]

给你由整数组成的山脉数组 arr ,返回满足 arr[0] < arr[1] < ... arr[i - 1] < arr[i] > arr[i + 1] > ... > arr[arr.length - 1] 的下标 i

你必须设计并实现时间复杂度为 O(log(n)) 的解决方案。

示例 1:

输入:arr = [0,1,0]
输出:1

示例 2:

输入:arr = [0,2,1,0]
输出:1

示例 3:

输入:arr = [0,10,5,2]
输出:1

提示:

  • 3 <= arr.length <= 105
  • 0 <= arr[i] <= 106
  • 题目数据保证 arr 是一个山脉数组

🌻算法原理

题目说了,这些数据必是一个山峰数组,所以我们可以直接暴力的将其遍历,找出前一个数小于当前数的位置,但有个要求是时间复杂度为O(log(n))

由于这个数组必是山峰数组,那么它是具有二段性的,所以我们可以采用二分查找

image-20231122155510906

代码实现

class Solution {
public:int peakIndexInMountainArray(vector<int>& arr) {int left = 1;   //初始位置和末尾位置必不可能是峰顶int right = arr.size()-1 -1;while(left < right){int mid = left + (right - left + 1) / 2;if(arr[mid] > arr[mid-1])	left = mid;else	right = mid-1;}return left;}
};

🐧162. 寻找峰值

🌼题目

题目链接:162. 寻找峰值 - 力扣(LeetCode)

峰值元素是指其值严格大于左右相邻值的元素。

给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。

你可以假设 nums[-1] = nums[n] = -∞

你必须实现时间复杂度为 O(log n) 的算法来解决此问题。

示例 1:

输入:nums = [1,2,3,1]
输出:2
解释:3 是峰值元素,你的函数应该返回其索引 2。

示例 2:

输入:nums = [1,2,1,3,5,6,4]
输出:1 或 5 
解释:你的函数可以返回索引 1,其峰值元素为 2;或者返回索引 5, 其峰值元素为 6。

提示:

  • 1 <= nums.length <= 1000
  • -231 <= nums[i] <= 231 - 1
  • 对于所有有效的 i 都有 nums[i] != nums[i + 1]

🌻算法原理

我们可以暴力解法,遍历这个数组,如果开始下降,则可以返回该位置的值;如果一直向上,则返回最后一个位置的即可。这里最坏的情况就是走到最后一个位置,时间复杂度为O(N)。

image-20231122163658867

在此基础上,我们可以优化这个暴力解法,我们抽象这个数组:

  • 选定某i位置,当前位置大于i+1,此时是一个下降区域,那么在i的左边区域,肯定会有一个上升区域(因为左右都是负无穷),而右边区域不一定有结果,因为右边也是负无穷,可能会一直下降到负无穷大

    image-20231122165010966

  • 如果选的的i位置,小于i+1位置的元素,那么这个区域此时是一个上升区域,那么在i的右边区域,肯定会有一个下降区域
    image-20231122165037717

通过这两种情况的抽象,虽然这个数组是一个完全无序的数组,但是它具有二段性,那么我们就可以采用二分查找的思想

image-20231122165312487

🌷代码实现

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

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

🌼题目

题目链接:153. 寻找旋转排序数组中的最小值 - 力扣(LeetCode)

已知一个长度为 n 的数组,预先按照升序排列,经由 1n旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:

  • 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
  • 若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]

注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]]

给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

输入:nums = [3,4,5,1,2]
输出:1
解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。

示例 2:

输入:nums = [4,5,6,7,0,1,2]
输出:0
解释:原数组为 [0,1,2,4,5,6,7] ,旋转 4 次得到输入数组。

示例 3:

输入:nums = [11,13,15,17]
输出:11
解释:原数组为 [11,13,15,17] ,旋转 4 次得到输入数组。

提示:

  • n == nums.length
  • 1 <= n <= 5000
  • -5000 <= nums[i] <= 5000
  • nums 中的所有整数 互不相同
  • nums 原来是一个升序排序的数组,并进行了 1n 次旋转

🌻算法原理

这就只有一个数组,我们可以直接暴力求解,直接遍历整个数组,找出最小值,直接遍历的时间复杂度为O(N)

由于题目说这是一个预先有序的数组,旋转得到的,所以这个数组是有二段性的

image-20231122172906435

  • A~B区域:nums[i] > nums[n-1]
  • C~D区域:nums[i] <= nums[n-1]

image-20231122173310454

🌷代码实现

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

🦖LCR 173. 点名

🌼题目

题目链接:LCR 173. 点名 - 力扣(LeetCode)

某班级 n 位同学的学号为 0 ~ n-1。点名结果记录于升序数组 records。假定仅有一位同学缺席,请返回他的学号。

示例 1:

输入: records = [0,1,2,3,5]
输出: 4

示例 2:

输入: records = [0, 1, 2, 3, 4, 5, 6, 8]
输出: 7

提示:

1 <= records.length <= 10000

🌻算法原理

这题还是比较简单,但是有很多种方法

  1. 哈希表
  2. 直接遍历
  3. 位运算
  4. 高斯求和

这四种解法,时间复杂度都是O(N)

该题目说,学号从0开始,那么在断开之前,整个数组对应的下标和元素是相等的,从断开位置开始,元素都是比下标大1的,这又出现了二段性,那么就可以采用二分查找

image-20231122175207994

有可能整个数组完全不缺,例如0,1,2,3那么我们缺少的就是4,所以最后还需要处理边界情况

🌷代码实现

class Solution {
public:int takeAttendance(vector<int>& records) {int left = 0;int right = records.size()-1;while(left < right){int mid = left + (right - left)/2;if(records[mid] == mid)left = mid+1;elseright = mid;}return records[left]==left?left+1:left;}
};

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

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

相关文章

python-opencv划痕检测-续

python-opencv划痕检测-续 这次划痕检测&#xff0c;是上一次划痕检测的续集。 处理的图像如下&#xff1a; 这次划痕检测&#xff0c;我们经过如下几步: 第一步&#xff1a;读取灰度图像 第二步&#xff1a;进行均值滤波 第三步&#xff1a;进行图像差分 第四步&#xff1…

java创建指定分辨率的图片或修改图片的分辨率(DPI)

因为java默认的图片像素分辨率DPI72&#xff0c;分辨率有点低。所以研究了一下如何创建指定DPI的方案。 DPI&#xff1a; 指的是每英尺的像素点(dots per inch) JPEG图片 JPEG图片的元数据定义参看oracle官网。 https://docs.oracle.com/javase/8/docs/api/javax/imageio/me…

VulnHub DC-9

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏…

2011-2022年地级市互联网普及率数据

2011-2022年地级市互联网普及率数据 1、时间&#xff1a;2011-2022年 2、指标&#xff1a;行政区划代码、年份、地区、互联网宽带接入用户_千户、常住人口数_千人、户籍人口数_千人、每百人互联网宽带用户_常住人口口径、每百人互联网宽带用户_户籍人口口径 3、来源&#xf…

c语言编程(模考2)

简答题1 从键盘输入10个数&#xff0c;统计非正数的个数&#xff0c;并且计算非正数的和 #include<stdio.h> int main() {int i,n0,sum0;int a[10];printf("请输入10个数&#xff1a;");for(i0;i<10;i){scanf("%d",&a[i]);}for(i0;i<10…

【C++】类型转换

文章目录 C语言中的类型转换为什么C需要四种类型转换C强制类型转换static_castreinterpret_castconst_castdynamic_cast RTTI常见面试题 C语言中的类型转换 在C语言中&#xff0c;如果 赋值运算符左右两侧类型不同&#xff0c;或者形参与实参类型不匹配&#xff0c;或者返回值…

12英寸双轴半自动划片机:颠覆传统划切工艺的五大优势

随着科技的飞速发展&#xff0c;半导体行业对精密划切设备的需求日益增长。在这篇文章中&#xff0c;我们将深入探讨12英寸双轴半自动划片机的优势&#xff0c;这种划片机在半导体制造过程中扮演着至关重要的角色。以下是这种划片机的五大优势。 一、高精度划切 12英寸双轴半自…

【数据结构初阶】栈和队列

栈和队列 1.栈1.1栈的概念和结构1.2栈的实现 2.队列2.1队列的概念和结构2.2队列的实现 1.栈 1.1栈的概念和结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。…

OSG文字-HUD显示汉字示例(3)

显示文字是一种非常实用的技术&#xff0c;可以用来把一些重要的文字始终显示在屏幕上。HUD的全称是HeadsUpDisplay&#xff0c;即抬头显示&#xff0c;这种技术最早应用在军事战斗机上。 创建HUD显示的基本步骤如下: <1> 创建一个osg::Camera对象&#xff0c;设置视图、…

kubernetes学习-概念3

工作负载资源 Kubernetes 提供了几个内置的 API 来声明式管理工作负载及其组件。 最终&#xff0c;你的应用以容器的形式在 Pods 中运行&#xff1b; 但是&#xff0c;直接管理单个 Pod 的工作量将会非常繁琐。例如&#xff0c;如果一个 Pod 失败了&#xff0c;你可能希望运行…

lombok 引入

lombok 依赖--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>

ARCGIS网络分析

一、实验名称&#xff1a; 网络分析 二、实验目的&#xff1a; 通过本实验练习&#xff0c;掌握空间数据网络分析的基本方法。 三、实验内容和要求&#xff1a; 实验内容&#xff1a; 利用ARCGIS软件网络分析工具及相关空间数据&#xff0c;查找距离“名人故居”、“博物…

Linux-进程替换

进程程序替换目的 首先我们要知道&#xff0c;创建子进程的目的是什么&#xff1f; 想让子进程执行父进程代码的一部分想让子进程执行一个全新的代码 我们之前所写的程序&#xff0c;子进程都是在执行父进程代码的一部分&#xff0c;而要想让子进程执行全新的代码&#xff0…

Mysql 8.0主从复制模式安装(兼容Mysql 5.7)

Mysql V8.0.35安装 官网地址&#xff1a;MySQL :: Download MySQL Community Server 下载【Mysql 8.0.35】压缩包 解压压缩包&#xff0c;仅保留6个安装文件即可 mysql-community-client-8.0.31-1.el7.x86_64.rpm mysql-community-client-plugins-8.0.31-1.el7.x86_64.rpm my…

马斯克震撼演讲:我想创立一个新世界

目录 1拼多多杀入大模型领域&#xff1a;年薪百万招聘人才 2马斯克震撼演讲&#xff1a;我想创立一个新世界 3文心4.0上线首交答卷&#xff1a;百度2023Q3成色如何 1拼多多杀入大模型领域&#xff1a;年薪百万招聘人才 快科技11月22日消息&#xff0c;据国内媒体报道&#x…

Linux C IO复用

IO复用 概述IO模型阻塞式IO非阻塞式IOIO复用select、poll、epoll异同 信号驱动式IO异步IO select函数select示例代码 poll函数poll示例代码 epoll函数创建  epoll_create注册、修改、删除  epoll_ctl轮询 I/O 事件的发生  epoll_waitepoll示例代码 基于TCP和epoll在线多人…

赞!优雅的Python多环境管理神器!易上手易操作!

前言 Python 的不同版本之间常常存在依赖关系和兼容性问题&#xff0c;为了方便开发人员在 不同项目中使用不同的版本 。 如果大家使用过Python版本管理工具&#xff0c;肯定大多数人使用的都是Anaconda&#xff0c;它是一个优秀的数据科学开发环境&#xff0c;本身也提供了丰…

通达信吊灯止损指标公式,根据波动幅度自动调整止盈止损

吊灯止损指标是由查克勒博(Chuck LeBeau)发明的&#xff0c;亚历山大埃尔德(Alexander Elder)在其著作《走进我的交易室》中介绍了这种止盈止损方法&#xff08;中文版翻译为倒挂式离场法则&#xff09;&#xff0c;它是根据平均真实波幅ATR设置跟踪止损。吊灯止损指标的目的是…

Redis性能压测、监控工具及优化方案

Redis是一款高性能的开源缓存数据库&#xff0c;但是在实际应用中&#xff0c;我们需要对Redis进行性能压测、监控以及优化&#xff0c;以确保其稳定性和高可用性。本文将介绍Redis性能压测、监控工具及优化方案。 01 Redis性能压测 常用的Redis性能压测工具有&#xff1a; …

909-2015-T3

文章目录 1.原题2.算法思想2.1.求树的高度2.2.求路径 3.关键代码4.完整代码5.输出结果 1.原题 试编写算法&#xff0c;求给定二叉树上从根节点到叶子节点的一条路径长度等于树的深度减一的路径&#xff08;即列出从根节点到该叶子节点的节点序列&#xff09;&#xff0c;若这样…