力扣刷题:在排序数组中查找元素的第一个和最后一个位置

题目:

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

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

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

示例 1:

输入:nums = 5,7,7,8,8,10, target = 8

输出:3,4

示例 2:

输入:nums = 5,7,7,8,8,10, target = 6

输出:-1,-1

示例 3:

输入:nums = \[\], target = 0

输出:-1,-1

解析:

由于题目对时间复杂度的限制,在这里使用二分查找的思路更加的方便,这里与二分查找略微不同,需要设置一个index表示向左或者向右的边界情况,index代表了左右边界的索引

具体代码:

javascript 复制代码
/**
 * 在已排序数组中查找目标值的起始和结束位置
 * @param {number[]} nums - 已排序的升序数组
 * @param {number} target - 要查找的目标值
 * @return {number[]} - 返回包含起始和结束位置的数组,如果未找到则返回[-1, -1]
 */
var searchRange = function(nums, target) {
    // 查找目标值的左边界(第一次出现的位置)
    let left = search(nums, target, true);
    // 查找目标值的右边界(最后一次出现的位置)
    let right = search(nums, target, false);
    // 返回结果数组
    return [left, right];
};

/**
 * 二分查找辅助函数,用于查找目标值的边界
 * @param {number[]} nums - 已排序的升序数组
 * @param {number} target - 要查找的目标值
 * @param {boolean} isLeft - 标识查找的是左边界(true)还是右边界(false)
 * @return {number} - 返回找到的边界索引,未找到则返回-1
 */
function search(nums, target, isLeft) {
    // 初始化二分查找的左右指针
    let left = 0;
    let right = nums.length - 1;
    // 初始化结果索引为-1(表示未找到)
    let index = -1;
    
    // 二分查找主循环
    while (left <= right) {
        // 计算中间索引
        let mid = Math.floor((left + right) / 2);
        
        if (nums[mid] > target) {
            // 中间值大于目标值,在左半部分继续查找
            right = mid - 1;
        } else if (nums[mid] < target) {
            // 中间值小于目标值,在右半部分继续查找
            left = mid + 1;
        } else {
            // 找到目标值,记录当前索引
            index = mid;
            
            if (isLeft) {
                // 如果是查找左边界,继续在左半部分查找更早出现的位置
                right = mid - 1;
            } else {
                // 如果是查找右边界,继续在右半部分查找更晚出现的位置
                left = mid + 1;
            }
        }
    }
    
    // 返回找到的边界索引(如果未找到则为-1)
    return index;
}
相关推荐
罗西的思考10 小时前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
CSharp精选营12 小时前
关系型 vs 非关系型:从原理到选型,一文搞定数据库核心分类
数据结构·nosql·关系型数据库·非关系型数据库·技术选型
美团技术团队13 小时前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
To_OC1 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC1 天前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
BadBadBad__AK1 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
_清歌2 天前
DSpark 深度解读:DeepSeek-V4 如何用「半自回归」把推理速度提升 85%
算法
统计实现局2 天前
SVD 的三步走:双对角化、Givens 收敛、排序
算法
躬行见万象2 天前
《VLA 系列》UniLab 强化训练 | G1 机器人 |复现
算法