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

news2025/1/16 8:15:40

在这里插入图片描述

文章目录

    • 🦜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;
            else
                left = 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;
            else
                right = 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;
            else
                right = mid;
        }
        return records[left]==left?left+1:left;
    }
};

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

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

相关文章

成为AI产品经理——AI产品经理工作全流程

一、业务背景 背景&#xff1a;日常排球训练&#xff0c;中考排球项目和排球体测项目耗费大量人力成本和时间成本。 目标&#xff1a;开发一套用于实时检测排球运动并进行排球垫球计数和姿势分析的软件。 二、产品工作流程 我们这里对于产品工作流程的关键部分进行讲解&…

GIT实践与常用命令---回退

实践场景 场景1 回退提交 在日常工作中&#xff0c;我们可能会和多个同事在同一个分支进行开发&#xff0c;有时候我们可能会出现一些错误提交&#xff0c;这些错误提交如果想撤销&#xff0c;可以有两种解决办法:回退( reset )、反做(revert) keywords&#xff1a;reset、rev…

什么是应急演练脚本?其设计原则是什么?

应急演练脚本是一种系统性、有计划的模拟性文件&#xff0c;旨在测试和评估组织在紧急情况下的应对能力。这种脚本提供了一系列步骤和场景&#xff0c;以确保团队能够高效、协调地应对各种紧急事件。以下将详细探讨应急演练脚本的定义、设计原则以及实施过程。 一、应急演练脚本…

解决“Error: xxx.js 已被代码依赖分析忽略,无法被其他模块引用”的报错

开发微信小程序的时候&#xff0c;报错内容如下&#xff1a; 错误原因&#xff1a; 微信开发者工具从 1.05.2201210 版本开始&#xff0c;对小程序项目新增了无依赖文件过滤能力。 如果某个 js 文件被静态分析显示是无依赖文件&#xff0c;在实际运行时又被其他 js 文件 req…

软件测试最新面试文档(总共212页)

1、自动化代码中,用到了哪些设计模式? 单例设计模式工厂模式PO设计模式数据驱动模式面向接口编程设计模式 2、什么是断言( Assert) ? 断言Assert用于在代码中验证实际结果是不是符合预期结果&#xff0c;如果测试用例执行失败会抛出异常并提供断言日志 3、什么是web自动化…

【LeetCode二叉树进阶题目】606,102,107

二叉树进阶题目 606. 根据二叉树创建字符串解题思路及实现 102. 二叉树的层序遍历解题思路及实现 107. 二叉树的层序遍历 II解题思路及实现 606. 根据二叉树创建字符串 描述 给你二叉树的根节点 root &#xff0c;请你采用前序遍历的方式&#xff0c;将二叉树转化为一个由括号…

SageMath安装

Sagemath工具是免费开源的&#xff0c;针对数学计算的一个工具。 网页版免安装&#xff1a;https://sagecell.sagemath.org/ Sagemath是根据Linux系统编写的&#xff0c;所以Windows上使用的话&#xff0c;会创建一个Linux系统运行。 1. 安装 Windows本地安装参考&#xff1…

服务器系列之 成功解决 com.jcraft.jsch.JSchException: Auth fail

我 | 在这里 &#x1f575;️ 读书 | 长沙 ⭐软件工程 ⭐ 本科 &#x1f3e0; 工作 | 广州 ⭐ Java 全栈开发&#xff08;软件工程师&#xff09; &#x1f383; 爱好 | 研究技术、旅游、阅读、运动、喜欢流行歌曲 &#x1f3f7;️ 标签 | 男 自律狂人 目标明确 责任心强 ✈️公…

系列八、key是弱引用,gc垃圾回收时会影响ThreadLocal正常工作吗

一、key是弱引用&#xff0c;gc垃圾回收时会影响ThreadLocal正常工作吗 到这里&#xff0c;有些小伙伴可能有疑问&#xff0c;ThreadLocalMap的key既然是 弱引用&#xff0c;那么GC时会不会贸然地把key回收掉&#xff0c;进而影响ThreadLocal的正常使用呢&#xff1f;答案是不会…

使用EasyPlayer播放H.265视频流

使用EasyPlayer播放H.265视频流 EasyPlayer流媒体视频播放器 EasyPlayer流媒体视频播放器 EasyPlayer流媒体视频播放器可支持H.264与H.265编码格式&#xff0c;性能稳定、播放流畅&#xff0c;能支持RTSP、RTMP、HLS、FLV、WebRTC等格式的视频流播放&#xff0c;并且已实现网页…

TensorFlow实战教程(十七)-Keras搭建分类神经网络及MNIST数字图像案例分析

从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前一篇文章详细讲解了Keras环境搭建、入门基础及回归神经网络案例。本篇文章将通过Keras实现分类学习,以MNIST数字图片为例进行讲解。基础性文章,希望对您有所帮助! 一.什么是分类学习 1.Classifica…

JMeter —— 接口自动化测试(数据驱动)

前言 之前我们的用例数据都是配置在HTTP请求中&#xff0c;每次需要增加&#xff0c;修改用例都需要打开JMeter重新编辑&#xff0c;当用例越来越多的时候&#xff0c;用例维护起来就越来越麻烦&#xff0c;有没有好的方法来解决这种情况呢&#xff1f;我们可以将用例的数据存…

Java小游戏之飞翔的小鸟

创建三个包&#xff0c;存放代码。把图片放进文件中 APP包&#xff08;运行&#xff09; GameApp类 package APP; import mian.GameFrame;public class GameApp {public static void main(String[] args) {new GameFrame();} } mian包&#xff08;主内容&#xff09; Barrie…

03梯度下降

目录 lambda基础知识 代码 核心算法&#xff1a; lambda基础知识 lambda 是 Python 中的一个关键字&#xff0c;用于创建匿名函数。匿名函数是一种没有具体名称的小型、临时的函数&#xff0c;通常用于一次性的、简单的操作。lambda 函数的语法如下&#xff1a;python Copy c…

3d标签云实现过程(tagcloud.js)同步原生和 vue

写在前面 本来是没有准备写这个知识点&#xff0c;但是下载这个 js 的时候发现很多都是要钱或者是积分的&#xff0c;我就不明白了一个开源了这么久的 js 怎么还有人拿来挣钱的&#xff0c;同时还有一些只有原生 html 的例子&#xff0c;但是现在都是 框架主导的一些项目&#…

2017年全国硕士研究生入学统一考试管理类专业学位联考数学试题——解析版

文章目录 2017 级考研管理类联考数学真题解析一、问题求解&#xff08;本大题共 5 小题&#xff0c;每小题 3 分&#xff0c;共 45 分&#xff09;下列每题给出 5 个选项中&#xff0c;只有一个是符合要求的&#xff0c;请在答题卡上将所选择的字母涂黑。真题&#xff08;2017-…

Android : ListView + BaseAdapter-2简单应用

​​容器与适配器&#xff1a;​​​​​ http://t.csdnimg.cn/ZfAJ7 实体类 News.java package com.example.mylistviewadapter2.entity;public class News {private String title;private String content;private int img;public News(String title, String conte…

蓝桥杯物联网_STM32L071_2_继电器控制

CubeMX配置&#xff1a; Function.c及Function.h&#xff1a; #include "Function.h" #include "gpio.h" void Function_LD5_ON(void){HAL_GPIO_WritePin(LD5_GPIO_Port, LD5_Pin, GPIO_PIN_RESET); }void Function_LD5_OFF(void){HAL_GPIO_WritePin(LD5_…

O2OA(翱途)开发平台 V8.2已发布,更安全、更高效、更开放

尊敬的 O2OA (翱途) 平台合作伙伴、用户以及亲爱的开发小伙伴们&#xff0c;V8.2 版本已正式发布&#xff0c;大家可以去官网上下载最新版本。 上次 8.1 的发布是在 9 月 1 日&#xff0c;又过去两个多月&#xff0c;O2OA 研发团队始终踏踏实实地做好产品的研发及优化工作&…

01背包与完全背包学习总结

背包问题分类见下图 参考学习点击&#xff1a;代码随想录01背包讲解 01背包问题&#xff1a; 核心思路&#xff1a; 1、先遍历物品个数&#xff0c;再遍历背包容量。因为容量最先是最大的&#xff0c;往背包里放物品&#xff0c;所以背包容量在慢慢减少&#xff0c;但背包容量…