【专题刷题】二分查找(二)

📝前言说明:

  • 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录,按专题划分
  • 每题主要记录:(1)本人解法 + 本人屎山代码;(2)优质解法 + 优质代码;(3)精益求精,更好的解法和独特的思想(如果有的话)
  • 文章中的理解仅为个人理解。如有错误,感谢纠错

🎬个人简介:努力学习ing
📋本专栏:C++刷题专栏
📋其他专栏:C语言入门基础,python入门基础,C++学习笔记,Linux
🎀CSDN主页 愚润泽

视频

  • 69. x 的平方根
    • 个人解
  • 35. 搜索插入位置
    • 个人解
  • 852. 山脉数组的峰顶索引
    • 个人解
  • 162. 寻找峰值
    • 个人解
  • 153. 寻找旋转排序数组中的最小值
    • 个人解
    • 优质解
  • LCR 173. 点名
    • 个人解


69. x 的平方根

在这里插入图片描述

个人解

思路:

  • 确定答案区间:[0, min(x, 46341)](46341 是 2^31 - 1 的平方根 + 1)
  • 问题转换成:找平方 <= x 的右端点(因为题目向下取整)
  • mid选取判断:因为向下取整,left = mid会死循环

用时:
屎山代码:

class Solution {
public:int mySqrt(int x) {int left = 0, right = min(x, 46341);while(left < right) {unsigned int mid = left + (right - left + 1) / 2;if(mid * mid <= x)left = mid;elseright = mid - 1;}return left;}
};

时间复杂度:O(n)
空间复杂度:O(1)


35. 搜索插入位置

在这里插入图片描述

个人解

思路:

  • 题目意思:有target就返回target,没有就返回 >target 的第一个位置
  • 总结一下:就是返回 >= target 的第一个位置
  • 细节处理:模拟三种情况:1,正常找到target或者正常在数组中间插入;2,全部值都小于target;3,全部值都大于target(在这道题中要特殊处理全小于target的情况)

用时:5:00
屎山代码:

class Solution {
public:int searchInsert(vector<int>& nums, int target) {int left = 0, right = nums.size() - 1;while(left < right){int mid = left + (right - left) / 2;if(nums[mid] < target)left = mid + 1;elseright = mid;}// 特殊处理全小于target的情况if(nums[right] >= target)return right;elsereturn nums.size();}
};

时间复杂度:O(logN)
空间复杂度:O(1)


852. 山脉数组的峰顶索引

在这里插入图片描述

个人解

思路:

  • 二段性:每次和右边的数比较
  • 右边的数不存在 / 右边的数 <= 当前数:山峰肯定在 [left, mid]
  • 右边的数 > 当前数:山峰肯定在 [mid + 1, right]

用时:5:00
屎山代码:

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

时间复杂度:O(logN)
空间复杂度:O(1)


162. 寻找峰值

在这里插入图片描述
在这里插入图片描述

个人解

思路:

  • 这道题的提示3:nums[i] != nums[i + 1],太重要了(保证了一定有一个峰值)
  • 每次和右侧数字比较
  • > 右侧的数字:峰值一定在[left ,mid](mid有可能是峰值)
  • < 右侧的数字:峰值一定在[mid + 1, right]

用时:10:00(一开始没看到提示3)
屎山代码:

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;elseleft = mid + 1;}return right;}
};

时间复杂度:O(logN)
空间复杂度:O(1)


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

个人解

思路:

  • 利用数组的有序性二分,找最小
  • 但是问题在于:这里在翻转以后可能出现两段数组!一段数组上查找的时候,要判断最小值会不会出行在另一段数组上
  • 如何判断呢?如果真的有两段数组,则第二段数组的最大值一定是nums[n-1],如果当前nums[mid] < nums[n - 1]代表在正确的数组上查找了,反之就是在错误的数组上查找了,要让left移动到右边

用时:15:00
屎山代码:

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

时间复杂度:O(log n)
空间复杂度:O(1)


优质解

看了官方题解以后想到的:
在这里插入图片描述

  • 如果翻转了,产生了两个数组,则最小值,一定在第二个数组上!!!
  • 并且,前一个数组的元素都大于第二个数组的元素
  • 那我们的比较基准就可以和最后一个值进行比较
  • > nums[n-1]:数组错了,答案一定在[mid + 1, right]
  • < nums[n-1]:答案一定在[left, mid]mid也有可能是答案

代码:

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

LCR 173. 点名

个人解

思路:

  • 因为数组是升序排序的,且学号从0开始,利用学号和下标对应的特点,找出缺失值在哪一遍
  • mid == records[mid] ,则缺失值在 [mid + 1, right]
  • mid > records[left, mid]
  • 特殊判断,最后一个同学缺席

用时:7:00
屎山代码:

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

时间复杂度:O(log n)
空间复杂度:O(1)


🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

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

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

相关文章

Java—ThreadLocal底层实现原理

首先&#xff0c;ThreadLocal 本身并不提供存储数据的功能&#xff0c;当我们操作 ThreadLocal 的时候&#xff0c;实际上操作线程对象的一个名为 threadLocals 成员变量。这个成员变量的类型是 ThreadLocal 的一个内部类 ThreadLocalMap&#xff0c;它是真正用来存储数据的容器…

Elasticsearch(ES)中的脚本(Script)

文章目录 一. 脚本是什么&#xff1f;1. lang&#xff08;脚本语言&#xff09;2. source&#xff08;脚本代码&#xff09;3. params&#xff08;参数&#xff09;4. id&#xff08;存储脚本的标识符&#xff09;5. stored&#xff08;是否为存储脚本&#xff09;6. script 的…

客户联络中心能力与客户匹配方式

在数字化时代&#xff0c;客户联络中心作为企业与客户沟通的核心枢纽&#xff0c;其服务能力与客户需求的精准匹配至关重要。随着客户期望的不断提升&#xff0c;传统的“一刀切”服务模式已难以满足个性化需求&#xff0c;如何通过智能化的手段实现服务能力与客户的高效匹配&a…

深入理解网络原理:UDP协议详解

在计算机网络中&#xff0c;数据的传输是通过各种协议实现的&#xff0c;其中用户数据报协议&#xff08;UDP&#xff0c;User Datagram Protocol&#xff09;作为一种重要的传输层协议&#xff0c;广泛应用于实时通信、视频流、在线游戏等场景。本文将深入探讨UDP协议的特性、…

vscode切换Python环境

跑深度学习项目通常需要切换python环境&#xff0c;下面介绍如何在vscode切换python环境&#xff1a; 1.点击vscode界面左上角 2.在弹出框选择对应kernel

【MCP Node.js SDK 全栈进阶指南】中级篇(4):MCP错误处理与日志系统

前言 随着MCP应用的规模和复杂性增长,错误处理与日志系统的重要性也日益凸显。一个健壮的错误处理策略和高效的日志系统不仅可以帮助开发者快速定位和解决问题,还能提高应用的可靠性和可维护性。本文作为中级篇的第四篇,将深入探讨MCP TypeScript-SDK中的错误处理与日志系统…

【Qt】文件

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Qt 目录 一&#xff1a;&#x1f525; Qt 文件概述 二&#xff1a;&#x1f525; 输入输出设备类 三&#xff1a;&#x1f525; 文件读写类 四&#xff1a;&#x1f525; 文件和目录信息类 五&…

代码随想录算法训练营第五十八天 | 1.拓扑排序精讲 2.dijkstra(朴素版)精讲 卡码网117.网站构建 卡码网47.参加科学大会

1.拓扑排序精讲 题目链接&#xff1a;117. 软件构建 文章讲解&#xff1a;代码随想录 思路&#xff1a; 把有向无环图进行线性排序的算法都可以叫做拓扑排序。 实现拓扑排序的算法有两种&#xff1a;卡恩算法&#xff08;BFS&#xff09;和DFS&#xff0c;以下BFS的实现思…

Qt实现语言切换的完整方案

在Qt中实现语言动态切换需要以下几个关键步骤&#xff0c;我将提供一个完整的实现方案&#xff1a; 一、准备工作 在代码中使用tr()标记所有需要翻译的字符串 cpp button->setText(tr("Submit")); 创建翻译文件 在.pro文件中添加&#xff1a; qmake TRANSLATION…

面试中被问到mybatis与jdbc有什么区别怎么办

1. 核心区别 维度JDBCMyBatis抽象层级底层API&#xff0c;直接操作数据库高层持久层框架&#xff0c;封装JDBC细节代码量需要手动编写大量样板代码&#xff08;连接、异常处理等&#xff09;通过配置和映射减少冗余代码SQL管理SQL嵌入Java代码&#xff0c;维护困难SQL与Java代…

用于协同显著目标检测的小组协作学习 2021 GCoNet(总结)

摘要 一 介绍 问题一&#xff1a;以往的研究尝试利用相关图像之间的一致性&#xff0c;通过探索不同的共享线索[12, 13, 14]或语义连接[15, 16, 17]&#xff0c;来助力图像组内的共同显著目标检测&#xff08;CoSOD&#xff09;&#xff0c;什么意思&#xff1f; 一方面是探…

OpenCV 图形API(62)特征检测-----在图像中查找最显著的角点函数goodFeaturesToTrack()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 确定图像上的强角点。 该函数在图像或指定的图像区域内找到最显著的角点&#xff0c;如文献[240]中所述。 函数使用 cornerMinEigenVal 或 cor…

MySQL引擎分类与选择、SQL更新底层实现、分库分表、读写分离、主从复制 - 面试实战

MySQL引擎分类与选择、SQL更新底层实现、分库分表、读写分离、主从复制 - 面试实战 故事背景&#xff1a; 今天&#xff0c;我们模拟一场互联网大厂Java求职者的面试场景。面试官将针对MySQL的核心技术点进行提问&#xff0c;涵盖MySQL引擎分类与选择、SQL更新底层实现、分库…

如何确保微型导轨的质量稳定?

微型导轨在精密机械中扮演着至关重要的角色&#xff0c;它们不仅影响设备的性能&#xff0c;还决定了产品的寿命。那么&#xff0c;如何通过一些关键步骤来提高微型导轨的稳定性呢&#xff1f; 1、严格筛选供应商&#xff1a;选择具备高品质保证能力的供应商&#xff0c;确保原…

Golang编程拒绝类型不安全

简介 在 Go 中&#xff0c;标准库提供了多种容器类型&#xff0c;如 list、ring、heap、sync.Pool 和 sync.Map。然而&#xff0c;这些容器默认是类型不安全的&#xff0c;即它们可以接受任何类型的值&#xff0c;这可能导致运行时错误。为了提升代码的类型安全性和可维护性&am…

什么是 JSON?学习JSON有什么用?在springboot项目里如何实现JSON的序列化和反序列化?

作为一个学习Javaweb的新手&#xff0c;理解JSON的序列化和反序列化非常重要&#xff0c;因为它在现代Web开发&#xff0c;特别是Spring Boot中无处不在。 什么是 JSON&#xff1f; 首先&#xff0c;我们简单了解一下JSON (JavaScript Object Notation)。 JSON 是一种轻量级的…

iOS/Android 使用 C++ 跨平台模块时的内存与生命周期管理

在移动应用开发领域,跨平台开发已经成为一种不可忽视的趋势。随着智能手机市场的持续扩张,开发者需要同时满足iOS和Android两大主流平台的需求,而这往往意味着重复的工作量和高昂的维护成本。跨平台开发的目标在于通过一套代码库实现多平台的支持,从而降低开发成本、加速产…

【AAudio】A2dp sink创建音频轨道的源码流程分析

一、AAudio概述 AAudio 是 Android 8.0(API 级别 26)引入的 C/C++ 原生音频 API,专为需要低延迟、高性能音频处理的应用设计,尤其适用于实时音频应用(如音频合成器、音乐制作工具、游戏音效等)。 1.1 主要特点 低延迟:通过减少音频数据在内核与用户空间之间的拷贝,直…

Spring中配置 Bean 的两种方式:XML 配置 和 Java 配置类

在 Spring 框架中,配置 Bean 的方式主要有两种:XML 配置 和 Java 配置类。这两种方式都可以实现将对象注册到 Spring 容器中,并通过依赖注入进行管理。本文将详细介绍这两种配置方式的步骤,并提供相应的代码示例。 1. 使用 XML 配置的方式 步骤 创建 Spring 配置文件 创建…

海之淀攻略

家长要做的功课 家长可根据孩子情况&#xff0c;需要做好以下功课&#xff1a; 未读小学的家长&#xff1a;了解小学小升初派位初中校额到校在读小学的家长&#xff1a;了解小升初派位初中校额到校在读初中的家长&#xff1a;了解初中校额到校 越是高年级的家长&#xff0c;…