当前位置: 首页 > news >正文

【LeetCode题解】LeetCode 35. 搜索插入位置

【题目链接】
35. 搜索插入位置
【题目描述】
在这里插入图片描述
【题解】
通过题目可以知道这是一道经典的二分查找的题目,对于二分查找的题目,根据需要查找的两个边界点,分为两个不同的模板,如下图所示。
在这里插入图片描述
这道题要求在数组中查找目标值并返回其索引,若目标值不存在,则返回它按顺序插入的位置。因此,它适合使用绿色边界点对应的二分查找模板。
该模板适用于查找最小满足条件的值的场景,常用于定位满足特定条件的最小值或区间的左边界。其核心逻辑是通过不断收缩右边界,最终定位到符合条件的最小值。

其模板如下:

bool check(int x) {/* ... */} // 检查x是否满足某种性质int bsearch_2(int l, int r)
{while (l < r){int mid = l + r >> 1;if (check(mid)) r = mid;else l = mid + 1;}return l;
}

【AC代码】

class Solution {
public:int searchInsert(vector<int>& nums, int target) {int l = 0, r = nums.size();while(l < r) {int mid = l + r >> 1;if(nums[mid] >= target)r = mid;elsel = mid + 1;}return l;}
};

【思考】
1.能否使用红色边界点对应的模板呢?
这道题同样可以用红色边界点对应的模板来解答,只是需要先将问题转化为寻找最后一个小于目标值的元素位置,再通过推导得出插入位置。
该模板的核心是定位最后一个满足条件的位置(即右边界),而原问题实际需要的是第一个大于等于目标值的位置(即左边界)。两者的转化逻辑很明确:插入位置 = 最后一个小于目标值的位置 + 1,而寻找最后一个小于目标值的位置恰好是红色边界点模板的典型应用场景。

其模板如下:

bool check(int x) {/* ... */} // 检查x是否满足某种性质int bsearch_1(int l, int r)
{while (l < r){int mid = l + r + 1 >> 1;if (check(mid)) l = mid;else r = mid - 1;}return l;
}

【AC代码】

class Solution {
public:int searchInsert(vector<int>& nums, int target) {int l = 0, r = nums.size() - 1; while (l < r) {int mid = (l + r + 1) / 2; if (nums[mid] < target) { l = mid;} else {                  r = mid - 1;}}// 循环结束后,l是最后一个可能<target的位置,需判断是否真的满足if (nums[l] < target) {return l + 1; // 存在<target的元素,插入位置为l+1} else {return l;     // 所有元素≥target,插入位置为l(即第一个≥target的位置)}}
};

2.模板的两个边界lr如何确定?
在ac之前,我卡在了一个地方,r一直取的值是r = nums.size() - 1,这导致在测试样例时,示例1和示例2都可以通过,但输入3确报了错。通过调试输出排查后发现,问题的根源在于边界值的设置。
r = nums.size() - 1时,示例1:
l=0,r=3,mid=1,nums[mid]=3,3<target,l=mid+1=1+1=2;l=0,r=3,mid=1,nums[mid]=3,3<target,l=mid+1=1+1=2;l=0,r=3,mid=1,nums[mid]=3,3<target,l=mid+1=1+1=2;
l=2,r=3,mid=2,nums[mid]=5,5≥5,r=2;l=2,r=3,mid=2,nums[mid]=5,5≥5,r=2;l=2,r=3,mid=2,nums[mid]=5,55,r=2;
l=2,r=2,l=2,r=2,l=2,r=2,退出循环,返回l=2,答案正确
r = nums.size() - 1时,示例2:
l=0,r=3,mid=1,nums[mid]=3,3>target,r=1;l=0,r=3,mid=1,nums[mid]=3,3>target,r=1;l=0,r=3,mid=1,nums[mid]=3,3target,r=1;
l=0,r=1,mid=0,nums[mid]=1,1<target,l=mid+1=0+1=1;l=0,r=1,mid=0,nums[mid]=1,1<target,l=mid+1=0+1=1;l=0,r=1,mid=0,nums[mid]=1,1target,l=mid+1=0+1=1;
l=1,r=1,l=1,r=1,l=1,r=1,退出循环,返回l=1,答案正确
r = nums.size() - 1时,示例3:
l=0,r=3,mid=1,nums[mid]=3,3<target,l=mid+1=1+1=2;l=0,r=3,mid=1,nums[mid]=3,3<target,l=mid+1=1+1=2;l=0,r=3,mid=1,nums[mid]=3,3target,l=mid+1=1+1=2;
l=2,r=3,mid=2,nums[mid]=5,5<target,l=mid+1=2+1=3;l=2,r=3,mid=2,nums[mid]=5,5<target,l=mid+1=2+1=3;l=2,r=3,mid=2,nums[mid]=5,5target,l=mid+1=2+1=3;
l=3,r=3,l=3,r=3,l=3,r=3,退出循环,返回l=3,答案错误
通过上述分析可以发现,r = nums.size()的设置确保了搜索区间覆盖所有可能的插入位置,而r = nums.size() - 1会漏掉插入到数组末尾的情况,导致部分测试用例失败。
二分查找的核心是明确搜索区间的定义,并确保区间覆盖所有可能的解

http://www.dtcms.com/a/334526.html

相关文章:

  • [Linux] Linux逻辑卷管理
  • 知识点汇总linuxC高级 -2系统命令压缩与链接
  • RK3568 NPU RKNN(三):RKNN-ToolKit2模型构建与推理
  • 【LeetCode】算法详解#13 ---回文链表
  • Vue 3.5重磅更新:响应式Props解构,让组件开发更简洁高效
  • [Linux] Linux交换空间管理 Linux系统启动原理
  • 慧穗云开放平台 CDK 开票对接
  • echart中x的0位置出现柱子宽度被裁掉一部分的问题
  • 技术日记2025年08月16日
  • 基于FPGA的实时图像处理系统(1)——SDRAM回环测试
  • python---异常处理
  • Redis知识整理
  • 【论文笔记】STORYWRITER: A Multi-Agent Framework for Long Story Generation
  • 云服务平台主流架构的相关知识体系剖析
  • ABM和强化学习-2015年全国大学生数学建模竞赛B题
  • 安卓11 12系统修改定制化_____修改系统 解锁system分区 去除data加密 自由删减系统应用
  • JetPack系列教程(七):Palette——让你的APP色彩“飞”起来!
  • sql链接的url中serverTimezone的作用
  • 【大模型微调系列-04】 神经网络基础与小项目实战
  • windows环境下使用vscode以及相关插件搭建c/c++的编译,调试环境
  • GIMP:功能强大的跨平台图像处理软件
  • 嵌入式硬件篇---电容本质
  • leetcodehot100 矩阵置零
  • Jenkins安装部署(Win11)和常见配置镜像加速
  • B3837 [GESP202303 二级] 画三角形
  • csrf攻击
  • 11、软件需求工程
  • AMD Ryzen AI Max+ 395四机并联:大语言模型集群推理深度测试
  • 智能二维码刷卡人脸识别梯控控制器硬件规格书​
  • 【C++】高效资源管理四剑客:RVO、NRVO、std::move、RAII 深度解析