hot100 -- 二分查找

目录

前言

🎂搜索插入位置

🌼搜索二维矩阵

🌼排序数组元素第一和最后一个位置

🌼旋转排序数组

💪旋转排序数组中的最小值

💪两个正序数组的中位数


前言

二分算法学习_时间超限ac:0%-CSDN博客

🎂搜索插入位置

35. 搜索插入位置 - 力扣(LeetCode)

直接套博客里的万能模板不太行,万能模板只能处理下取整死循环的问题,但是本题:

目标值 target 不一定在数组里

class Solution {
public:int searchInsert(vector<int>& nums, int target) {int l = 0, r = nums.size() - 1;while (l <= r) {int m = (l + r) >> 1;if (target > nums[m])l = m + 1;else if (target < nums[m])r = m - 1;else {l = m;break;}}// 因为 l<=r 退出循环后, r 必然位于插入位置return l;}
};

🌼搜索二维矩阵

74. 搜索二维矩阵 - 力扣(LeetCode)

1)别混淆 mid 和 m,此处 m 是 m 行,mid 才是中间值

2)对第 3 种情况,target == matrix[][],进行处理

class Solution {
public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int m = matrix.size(), n = matrix[0].size();int l = 0, r = m*n - 1; // 二维转一维while (l < r) {int mid = (l + r + 1) >> 1;if (target > matrix[mid/n][mid%n]) // 一维转二维l = mid;else if (target < matrix[mid/n][mid%n])r = mid - 1;else {l = mid;break;}}return matrix[l/n][l%n] == target;}
};

🌼排序数组元素第一和最后一个位置

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)

1)利用 while (l <= r) { ... l = m + 1 ... r = m - 1 };  左闭右闭区间

退出循环时,l 的位置就是 >= target 的最小的数

r == l - 1

2)只需求出第一个位置,即可取巧得到最后一个位置,现在有二分函数 lowerbound(nums, target) 得到第一个位置,最后一个位置即 lowerbound(nums, target + 1) - 1

3)奇数个元素,m = (l + r) / 2,取到中间的元素;偶数个元素,因为整数默认下取整,会取中间两个元素左边那个

坑:

1)不要用 >> 1,要用 / 2,不知道力扣是不是不支持位移运算符(>> 1 会超出时间限制) 

2)如果想要从 r = m - 1 开始,那么最后应该 return r;   r 此时位于最后一个位置(详情看代码 2)(用例1模拟一下)

代码 1

class Solution {
public:// >= target 的最小的数的位置int lowerbound(vector<int>& nums, int target) {int l = 0, r = nums.size() - 1;while (l <= r) {int m = l + (r - l) / 2;if (target > nums[m])l = m + 1;elser = m - 1;}return l; // 第一个位置}vector<int> searchRange(vector<int>& nums, int target) {int start = lowerbound(nums, target);if (start >= nums.size() || nums[start] != target)return {-1, -1};int end = lowerbound(nums, target + 1) - 1;return {start, end};}
};

代码 2

class Solution {
public:// >= target 的最小的数的位置int lowerbound(vector<int>& nums, int target) {int l = 0, r = nums.size() - 1;while (l <= r) {int m = l + (r - l) / 2;if (target < nums[m])r = m - 1;elsel = m + 1;}return r; // 最后一个位置}vector<int> searchRange(vector<int>& nums, int target) {int end = lowerbound(nums, target);if (end < 0 || nums[end] != target)return {-1, -1};int start = lowerbound(nums, target - 1) + 1;return {start, end};}
};

🌼旋转排序数组

33. 搜索旋转排序数组 - 力扣(LeetCode)

1)二分时,套 while (l <= r) 的模板,mid 位于中间 OR 中间偏左位置

此时,[l, mid] OR [mid + 1, r],至少一个区间是有序的,所以对左右区间的有序分类讨论

class Solution {
public:int search(vector<int>& nums, int target) {int n = nums.size();int l = 0, r = n - 1;// 二分找到 k 的位置while (l <= r) {int mid = (l + r) / 2;// target 位于 midif (nums[mid] == target)return mid;// 左边有序else if (nums[l] <= nums[mid]) {// target 位于左边(不包括 mid)if (nums[l] <= target && target < nums[mid]) r = mid - 1;else l = mid + 1;}// 右边有序else {// target 位于右边(不包括 mid)if (nums[mid] < target && target <= nums[r])l = mid + 1;elser = mid - 1;}}return -1; // 未找到}
};

💪旋转排序数组中的最小值

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

上一题是找目标值,本题是找最小值(都满足部分有序)

本题每次旋转,将最后一个值提取到最前面

可以画几个例子多验证一下:2 0 1,1 2 0,3 4 5 2,5 2 3 4

最小值处于断崖的第一个位置,显而易见,肯定位于无序一边

所以每次压缩有序部分,到无序部分找,注意结合例子处理边界

class Solution {
public:int findMin(vector<int>& nums) {int n = nums.size();int l = 0, r = n - 1;while (l <= r) { // l < r 也行// 单调升序if (nums[l] <= nums[r]) // 用 = 防止单个元素时死循环return nums[l];int m = (l + r) / 2;// 左边有序if (nums[m] >= nums[l]) // 用 = 防止 r 跳过最小值l = m + 1; // 去右边找elser = m; // 不用 m-1 防止跳过最小值}return nums[l];}
};

💪两个正序数组的中位数

4. 寻找两个正序数组的中位数 - 力扣(LeetCode)

结合这篇博客理解一下,用删除(淘汰)的思路
寻找两个正序数组的中位数(292) | 小浩算法 (geekxh.com)

辅助数组 findKth(nums1, i, nums2, j, k),i, j 是两个数组起始索引,第 k 大元素

如果第一个数组起始位置 i + 2/k - 1 的值 < 第二个数组起始位置 j + 2/k - 1 的值

那么就淘汰掉第一个数组前 2/k 个元素,反之淘汰另一个数组前 2/k 个元素

直到 k == 1,此时比较两个数组起始第 1 个元素大小即可

或者一个数组为空(即 i >= nums1.size() 或 j >= nums2.size())

时间 O(log( max(m, n) ))

class Solution {
public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int n = nums1.size(), m = nums2.size();int left = (n + m + 1) / 2, right = (n + m + 2) / 2; // 中间值索引 left 和 rightreturn (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0;}// nums1 起始索引 i, nums2 起始索引 j, 返回合并数组 第 k 个元素(1开始算)int findKth(vector<int>& nums1, int i, vector<int>& nums2, int j, int k) {if (i >= nums1.size()) // nums1 空数组return nums2[j + k - 1];if (j >= nums2.size()) // nums2 空数组return nums1[i + k - 1];if (k == 1)return min(nums1[i], nums2[j]); // 返回较小值// 2/k 位置的值// 如果一个数组 k/2 处超出范围, 无法判断中位数是否位于这个数组// 但是另一个数组前 k/2 个肯定没有中位数// 取 MAX, 淘汰另一个数组前 k/2 个元素int mid1 = (i + k/2 - 1 < nums1.size()) ? nums1[i + k/2 - 1] : INT_MAX;int mid2 = (j + k/2 - 1 < nums2.size()) ? nums2[j + k/2 - 1] : INT_MAX;// 递归二分if (mid1 < mid2) // mid1 淘汰 k/2return findKth(nums1, i + k/2, nums2, j, k - k/2);else // mid2 淘汰 k/2return findKth(nums1, i, nums2, j + k/2, k - k/2);}
};

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

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

相关文章

2024年【起重机械指挥】考试及起重机械指挥新版试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 起重机械指挥考试考前必练&#xff01;安全生产模拟考试一点通每个月更新起重机械指挥新版试题题目及答案&#xff01;多做几遍&#xff0c;其实通过起重机械指挥试题及解析很简单。 1、【多选题】《中华人民共和国特…

【Androi】安卓发展历程详解

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

git推送代码到github拒绝推送的解决方案

这里描述一下本地推送的场景&#xff0c;首先我在码云上建立了一个前端项目&#xff0c;进行了自己的个性化开发&#xff0c;后期在github上创建了一个一样的项目仓库存放代码。使用webstorm进行代码开发。在下面这个位置可以选择推送的代码位置。 选择推送github仓库之后&…

Python深度学习基于Tensorflow(16)基于Tensorflow的对话实例

文章目录 基础数据清洗数据生成词汇表定义分词器并制作数据集构建Transformer模型并训练模型推理 Tensorflow 的核心就是注意力机制&#xff0c;在之前详细的介绍过&#xff0c;具体可以看这个&#xff1a;Python深度学习基于Tensorflow&#xff08;9&#xff09;注意力机制_te…

在Java中为什么对a赋值为10,在进行a++时还是等于10呢

首先我们看这样一组代码 public class demo1 {public static void main(String[] args) {int a10;aa;System.out.println(a);} } 结果&#xff1a;10不是在第二步有a操作吗&#xff1f;为什么还是10呢&#xff1f; a的执行步骤如下&#xff1a; 保存当前a的值&#xff08;即10…

websocket链接携带参数

前端创建链接时官方提供的构造函数 var aWebSocket new WebSocket(url, [protocols]); url&#xff1a;要连接的URL&#xff1b;这应该是WebSocket服务器将响应的URL。 protocols&#xff1a;可选&#xff1b;一个协议字符串或者一个包含协议字符串的数组。这些字符串用于指定…

智能语音电销机器人可以做哪些事情?ai语音机器人系统

智能语音电销机器人软件的出现&#xff0c;给很多企业都带来了福利&#xff0c;尤其是电销企业&#xff0c;不仅工作效率提升了&#xff0c;成本降低了&#xff0c;还能实现智能化管理客户的出现&#xff0c;给很多企业都带来了福利&#xff0c;尤其是电销企业&#xff0c;不仅…

python初学者笔记(八)——数字阶乘

#python初学者笔记&#xff08;8&#xff09;——数字阶乘 阶乘是基斯顿卡曼于 1808 年发明的运算符号,是数学术语,一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积。 下面利用Python编写数字阶乘 ##1.方法一:利用函数的方法&#xff0c;求输入值的阶乘 #coding…

WebAPI 前端开发流程:深度解析与实践探索

WebAPI 前端开发流程&#xff1a;深度解析与实践探索 在前端开发的世界里&#xff0c;WebAPI扮演着至关重要的角色&#xff0c;它作为前端与后端沟通的桥梁&#xff0c;确保了数据的流畅传输与功能的完整实现。本文将详细探讨WebAPI前端开发流程&#xff0c;从四个方面、五个方…

什么情况下需要配戴助听器

以下几种情况需要考虑配戴助听器&#xff1a; 1、听力无波动3个月以上的感音神经性听力障碍。如:先天性听力障碍、老年性听力障碍、噪声性听力障碍、突聋的稳定期等&#xff0c;均可选配合适的助听器。 2、年龄方面。使用助听器没有严格的年龄限制&#xff0c;从出生数周的婴…

深度学习Week16——数据增强

文章目录 深度学习Week16——数据增强 一、前言 二、我的环境 三、前期工作 1、配置环境 2、导入数据 2.1 加载数据 2.2 配置数据集 2.3 数据可视化 四、数据增强 五、增强方式 1、将其嵌入model中 2、在Dataset数据集中进行数据增强 六、训练模型 七、自定义增强函数 一、前言…

Geoserver源码解读一(环境搭建)

一、Github地址 https://github.com/geoserver/geoserver 1.1 克隆代码 git clone https://github.com/geoserver/geoserver.git 1.2 选择版本 版本选择参考我的上一篇文章 Geoserver 以及 Geotools各版本和jdk版本对照表 此处我选择的是兼容jdk8的最后一个版本 git che…

netty+springboot+vue聊天室(需要了解netty)

先看看这个使用websocket实现的聊天室&#xff0c;因为前端是使用websocket&#xff0c;和下面的demo的前端差不多就不解释实现原理&#xff0c;所以建议还是看看(要是会websocket的大佬请忽略) springbootwebsocketvue聊天室 目录 一、实现内容二、代码实现1.后端2.前端源码…

html+CSS+js部分基础运用17

在图书列表中&#xff0c;为书名“零基础学JavaScript”和“HTML5CSS3精彩编程200例”添加颜色。&#xff08;请用class或style属性实现&#xff09;&#xff0c;效果如下图1所示&#xff1a; 图1 图书列表 Class和style的综合应用。&#xff08;1&#xff09;应用class的对象、…

命令行打包最简单的android项目从零开始到最终apk文件

准备好需要的工具 AndroidDevTools - Android开发工具 Android SDK下载 Android Studio下载 Gradle下载 SDK Tools下载 jdk的链接我就不发出来,自己选择,我接下来用的是8版本的jdk和android10的sdk sdk的安装和环境变量的配置 sdk tool压缩包打开后是这样子,打开sdk mana…

高防CDN是如何应对DDoS和CC攻击的

高防CDN&#xff08;内容分发网络&#xff09;主要通过分布式的网络架构来帮助网站抵御DDoS&#xff08;分布式拒绝服务&#xff09;和CC&#xff08;挑战碰撞&#xff09;攻击。 下面是高防CDN如何应对这些攻击的详细描述&#xff1a; 1. DDoS攻击防护 DDoS攻击通过大量的恶…

SREC用什么软件编程:全面解析与编程工具选择

SREC用什么软件编程&#xff1a;全面解析与编程工具选择 在嵌入式系统开发中&#xff0c;SREC文件格式扮演着至关重要的角色&#xff0c;用于存储和传输二进制数据。然而&#xff0c;对于许多初学者和开发者来说&#xff0c;如何选择合适的软件来编写SREC文件却是一个令人困惑…

STM32串口DMA 空闲中断使用笔记

这里只记录注意要点&#xff1a; 1&#xff0c;要开启串口 全局中断 和对应的接收DMA 中断&#xff0c;两个中断必须同时开 2&#xff0c;裸机程序需要在主循环外调用一次 这个函数 HAL_UARTEx_ReceiveToIdle_DMA(&huart2, rx_buff, BUFF_SIZE); 3&#xff0c;要在串口中…

【动态规划-BM71 最长上升子序列(一)】

题目 BM71 最长上升子序列(一) 分析 dp[i] 考虑到下标i&#xff0c;其组成的最长上升子序列长度 可以用动态规划的原因&#xff1a; 到i的结果可以由到j &#xff08;j<i) 的结果推出&#xff0c;只需要判断下标j对应的数字是否比下标i 对应的字母小即可 注意&#xf…

vs2013 - 打包

文章目录 vs2013 - 打包概述installshield2013limitededitionMicrosoft Visual Studio 2013 Installer Projects选择哪种来打包? 笔记VS2013打包和VS2019打包的区别打包工程选择view打包工程中单击工程名称节点&#xff0c;就可以在属性框中看到要改的属性(e.g. 默认是x86, 要…