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

保定做网站多钱广州致峰网站建设

保定做网站多钱,广州致峰网站建设,同城推广,山西省大同市网站建设公司35. 搜索插入位置 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。请必须使用时间复杂度为 O(log n) 的算法。 解题思路总览 标准二分(lower_bound 半开…

35. 搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。请必须使用时间复杂度为 O(log n) 的算法。

解题思路总览

  1. 标准二分(lower_bound 半开区间写法)
  2. 标准二分(闭区间写法)
  3. 递归二分
  4. 利用 Java Arrays.binarySearch 封装处理
  5. 变体:位运算取中 / 防溢出与模板细节
  6. 拓展:未知长度数组的指数扩展 + 二分(非本题必需,思路扩展)

题目回顾:给定升序(非递减)整数数组 nums 与 target,若存在返回其索引,否则返回按顺序插入后仍保持有序的索引(即第一个 >= target 的位置)。要求 O(log n)。这就是典型的 lower_bound 问题。


思路一:标准二分(lower_bound 半开区间写法)

原理与适用场景:
采用半开区间 [l, r) 表示当前搜索范围,维持循环不变量:目标插入位置一定在 [l, r) 中。中点 mid = l + (r - l)/2。若 nums[mid] >= target,将可能的插入位置右边界收缩到 mid;否则抛弃左半包含 mid 的部分,令 l = mid + 1。最终 l == r 即为第一个 >= target 的位置:

  1. 若该位置在数组长度内且值等于 target,则它就是目标索引。
  2. 否则该位置就是插入点。
    半开区间避免处理 mid - 1 / mid + 1 时越界边界判断,模板简洁统一,可复用于各类 lower_bound / upper_bound 问题。

实现步骤:

  1. 令 l = 0, r = n(注意 r 为 n,而不是 n-1)。
  2. while(l < r):计算 mid。
  3. 若 nums[mid] >= target:r = mid;否则 l = mid + 1。
  4. 循环结束返回 l。

JAVA 代码实现:

public class SolutionLowerBound {// 返回 target 的索引或其应插入位置(第一个 >= target 的下标)public int searchInsert(int[] nums, int target) {int n = nums.length;              // 数组长度int l = 0;                        // 左边界(包含)int r = n;                        // 右边界(不包含)while (l < r) {                   // 区间非空int mid = l + (r - l) / 2;    // 取中,防溢出if (nums[mid] >= target) {    // mid 位置可能是第一个 >= targetr = mid;                  // 收缩右端到 mid} else {                      // nums[mid] < targetl = mid + 1;              // 插入点一定在 mid 右侧}}return l; // l == r 为第一个 >= target 的位置(可能等于 n)}
}

思路二:标准二分(闭区间写法)

原理与适用场景:
使用闭区间 [l, r]。循环条件 l <= r。维护答案变量 ans,记录第一个 >= target 的候选位置。每当 nums[mid] >= target,用 ans = mid 保存并 r = mid - 1 尝试更左;否则 l = mid + 1。最终若 ans 未被更新(保持初值 n)则插入位置在数组末尾。闭区间写法适合对传统二分 while(l <= r) 更熟悉的人。

实现步骤:

  1. ans = n(默认插入到末尾)。
  2. while(l <= r) 取 mid。
  3. 若 nums[mid] >= target:更新 ans,r = mid - 1。
  4. 否则 l = mid + 1。
  5. 返回 ans。

JAVA 代码实现:

public class SolutionClosedInterval {public int searchInsert(int[] nums, int target) {int n = nums.length;          // 长度int l = 0;                    // 左边界int r = n - 1;                // 右边界int ans = n;                  // 默认插入到末尾while (l <= r) {              // 闭区间还存在元素int mid = l + (r - l) / 2;// 中点if (nums[mid] >= target) {// mid 可能是答案ans = mid;            // 记录候选r = mid - 1;          // 尝试找更左} else {                  // nums[mid] < targetl = mid + 1;          // 去右区间}}return ans;                   // 第一个 >= target 的位置}
}

思路三:递归二分

原理与适用场景:
递归在区间 [l, r] 中寻找第一个 >= target 的位置。若 l > r 返回 n(表示未找到更小位置)。取 mid:

  1. 若 nums[mid] >= target:答案在左半或 mid,自身与左半递归返回值取最小。
  2. 否则在右半。
    递归深度 O(log n)。适合希望把二分统一为递归模板的场景。

实现步骤:

  1. 递归函数返回第一个 >= target 的索引或 n。
  2. 初始调用 dfs(nums, 0, n-1, target, n)。
  3. 返回结果。

JAVA 代码实现:

public class SolutionRecursiveLB {public int searchInsert(int[] nums, int target) {return dfs(nums, 0, nums.length - 1, target, nums.length);}private int dfs(int[] a, int l, int r, int target, int n) {if (l > r) {              // 区间空,返回 n 代表插入末尾return n;}int mid = l + (r - l) / 2;// 取中if (a[mid] >= target) {   // mid 可能为答案,继续探索左侧int left = dfs(a, l, mid - 1, target, n);return Math.min(mid, left); // 取更左的} else {                  // a[mid] < target,只能右侧return dfs(a, mid + 1, r, target, n);}}
}

思路四:利用 Java Arrays.binarySearch 封装处理

原理与适用场景:
Java 标准库 Arrays.binarySearch(nums, target) 返回:

  1. 若找到:返回 >=0 的索引。
  2. 若未找到:返回 (-(插入点) - 1)。插入点即第一个 > target 的下标,也即第一个 >= target(因为未找到等于)。
    因此直接解码即可得到答案。适合快速实现,降低样板代码量,但在某些面试中展示手写二分更能体现功底。

实现步骤:

  1. 调用 idx = Arrays.binarySearch(nums, target)。
  2. 若 idx >= 0 返回 idx。
  3. 否则插入点 = -idx - 1。
  4. 返回插入点。

JAVA 代码实现:

import java.util.Arrays; // 导入工具类public class SolutionLibrary {public int searchInsert(int[] nums, int target) {int idx = Arrays.binarySearch(nums, target); // 标准库二分if (idx >= 0) {          // 找到直接返回return idx;}// 未找到,idx = -(insertionPoint) - 1return -idx - 1;         // 解码得到插入点}
}

思路五:位运算取中 / 模板细节(属于写法优化,不单独改变复杂度)

原理与适用场景:
在极端性能场景可用 mid = (l + r) >>> 1(无符号右移)替代 l + (r - l)/2;在 Java 中 int 溢出时 l + r 可能为负导致结果错误,因此推荐使用 l + (r - l)/2 或 (l + r) >>> 1(当 l,r >=0 时安全)。属于实现细节优化,可结合思路一或二使用。

实现步骤:

  1. 在二分循环中用 mid = (l + r) >>> 1。
  2. 其余逻辑不变。

(示例略,因核心逻辑同思路一。)


思路六:拓展 - 未知长度数组 / 流式数据(指数扩展 + 二分)

原理与适用场景:
若无法直接获得数组长度(例如某些 API 仅支持 get(i) 且越界抛异常),可先指数扩展边界:

  1. 令 r = 1,不断检查 nums[r] 与 target 比较,若 nums[r] < target 则 r *= 2。
  2. 找到第一个 nums[r] >= target 或越界时停止,此时目标插入点一定在 (r/2, r] 内。
  3. 在这个区间执行常规二分。指数扩展步数 O(log pos),整体仍 O(log n)。
    本题已给定长度,不必使用,只作思维拓展。

实现步骤(高层):

  1. 边界扩展。
  2. 二分搜索 lower_bound。
  3. 返回结果。

补充说明(对比分析)

  1. 正确满足 O(log n) 的实现:思路一、二、三、四、六(六为扩展情景)。
  2. 复杂度:
    • 思路一/二/三/四:时间 O(log n),空间 O(1)(递归 O(log n))。
    • 思路六:时间 O(log n),空间 O(1)(若递归则 O(log n))。
  3. 推荐优先级:
    • 首选思路一(半开区间 lower_bound 模板)。
    • 需要展示传统写法可选思路二。
    • 递归视个人风格;库函数写法快速但展示度较低。
  4. 边界与健壮性:
    • 空数组:半开区间写法自动返回 0。
    • target 小于最小值 -> 返回 0。
    • target 大于最大值 -> 返回 n。
    • 全部元素相同:lower_bound 仍正确给出 0 或 n(若 target 更大)。
  5. 常见错误:
    • 闭区间写法退出条件混乱导致死循环(如用 while(l < r) 但更新 r = mid - 1)。
    • mid = (l + r)/2 可能溢出(极大数据时)。
    • 返回 r 或 l 搞错:需基于循环不变量严格推导。
  6. 测试用例建议:
    • nums=[1,3,5,6], target=5 -> 2
    • nums=[1,3,5,6], target=2 -> 1
    • nums=[1,3,5,6], target=7 -> 4
    • nums=[1,3,5,6], target=0 -> 0
    • nums=[], target=5 -> 0
    • nums=[1], target=1 -> 0
    • nums=[1], target=2 -> 1
    • nums=[1,1,1], target=1 -> 0
  7. 总结:本题本质是 lower_bound,掌握一套稳健模板(思路一)即可在同类区间定位、统计频次、插入位置等问题上快速迁移。

综上,采用半开区间 lower_bound 模板实现最简洁、低错率、可直接推广,是最推荐解法。

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

相关文章:

  • 内部优惠券网站建站wordpress doc预览
  • 建设网站的硬件专门做恐怖的网站
  • 在俄罗斯用钱让女性做h事情的网站天津网站优化建设
  • 哪家建设公司网站网站开发合同中的知识产权条款
  • 东莞网站推广方案网站开发需求图
  • 友情链接添加在网站中有什么用南昌seo优化
  • 公司网站的搭建方案建立的近义词
  • 网站开发有哪些术语深圳加盟网站建设
  • 商城平台网站开发深圳建网站需要什么服务器
  • 旅游电子商务网站建设论文wordpress 怎么添加即时联系窗口
  • 网站建设工作室 杭州中文域名注册收费标准
  • seo网站设计费用免费安全建网站
  • 山东专业网站解决方案制作做数据图网站
  • 浙江住房和城乡建设部网站奖励自己视频免费
  • 东乡做网站上饶做网站最好的公司
  • 做电影网站违法小猫济南网站建设公司
  • 宿豫区建设局网站做电台需要的文章从哪个网站找
  • 用vs2010做购物网站大连网站快速排名
  • 站长工具app凡客旗舰店
  • 临沂企业自助建站婚礼婚庆网站建设
  • 网站关键词排名分析好一点的网站是怎么做的
  • 秦皇岛网站优化网站建设合同建设方注意事项
  • 外贸英文网站建设安徽城乡建设 厅网站
  • 网站建设项目的费用做什么科目外发加工网有哪些正规的
  • 专门做黄漫的网站广州网站建设技术
  • 自己做公众号和小说网站推广wordpress 分类模板
  • 莱芜网站开发win2008系统asp网站建设
  • 线上做汉语教师网站网站被k申诉
  • 哪里有做ppt模板下载网站wordpress最大附件
  • 创建全国文明城市手抄报谷歌优化