当前位置: 首页 > 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.xdnf.cn/news/1309213.html

相关文章:

  • flowable汇总查询方式
  • ktg-mes 改造成 Saas 系统
  • Golang分布式事务处理方案
  • ROS move_base 混合功能导航 RealSense D435i + 3D 点云地图 + 楼层切换 + 路径录制 + 路径规划
  • 适合2D而非3D的游戏
  • Rust学习笔记(四)|结构体与枚举(面向对象、模式匹配)
  • 从舒适度提升到能耗降低再到安全保障,楼宇自控作用关键
  • 奈飞工厂 —— 算法优化实战推荐
  • JavaScript手录17-原型
  • 2025年生成式引擎优化(GEO)服务商技术能力评估报告
  • 【Docker】Ubuntu上安装Docker(网络版)
  • [创业之路-550]:公司半年度经营分析会 - 常见差距与根因分析示例
  • linux网络基础
  • 022 基础 IO —— 文件
  • Redis-plus-plus 安装指南
  • 161. Java Lambda 表达式 - 使用工厂方法创建 Predicates
  • 力扣(LeetCode) ——142. 环形链表 II(C语言)
  • OpenShift 4.19安装中的变化
  • Vue 3与React内置组件全对比
  • Hadoop面试题及详细答案 110题 (16-35)-- HDFS核心原理与操作
  • 音视频学习(五十四):基于ffmpeg实现音频重采样
  • 基于单片机的防酒驾系统设计
  • 我的世界Java版1.21.4的Fabric模组开发教程(十八)自定义传送门
  • 《C++进阶之继承多态》【多态:概念 + 实现 + 拓展 + 原理】
  • 超越“调参”:从系统架构师视角,重构 AI 智能体的设计范式
  • 嵌入式硬件篇---电感本质
  • VScode 使用遇到的问题
  • Git Revert 特定文件/路径的方法
  • 设计模式之【快速通道模式】,享受VIP的待遇
  • leetcode_ 739 每日温度