446 字
2 分钟
在排序数组中查找元素的第一个和最后一个位置

题目描述#

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]

你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

解题思路#

  1. 二分查找左边界
    • 查找第一个 ≥ target 的位置,若该值等于 target 则为左边界。
  2. 二分查找右边界
    • 查找第一个 > target 的位置,减一后若等于 target 则为右边界。
  3. 边界检查
    • 若左边界无效或值不匹配,返回 [-1, -1]

关键洞察#

  1. 两次二分
    • 左边界 = 首个 等于 target 的位置(lower_bound)。
    • 右边界 = 首个 大于 target 的位置 减一upper_bound - 1)。
  2. 统一框架
    • 两次查找均用 左闭右闭 区间,通过 mid 比较调整指针。
  3. 提前终止
    • 左边界未找到时,无需查右边界。

复杂度分析#

  • 时间复杂度O(log n) 两次独立的二分查找,每次 O(log n)
  • 空间复杂度O(1) 仅用常数额外空间存储指针。

代码实现#

/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var searchRange = function (nums, target) {
const search = (nums, target, leftRight) => {
let ans = -1;
let left = 0, right = nums.length - 1;
while (left <= right) {
const middle = left + Math.floor((right - left) / 2);
if (nums[middle] === target) {
ans = middle;
leftRight ? right = middle - 1 : left = middle + 1;
} else if (nums[middle] < target) {
left = middle + 1;
} else {
right = middle - 1;
}
}
return ans;
}
return [
search(nums, target, true),
search(nums, target, false)
]
};

相似题目#

在排序数组中查找元素的第一个和最后一个位置
https://website-truelovings-projects.vercel.app/posts/algorithms/在排序数组中查找元素的第一个和最后一个位置/
作者
欢迎来到StarSky的网站!
发布于
2025-08-06
许可协议
CC BY-NC-SA 4.0