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

题目:

给你一个按照非递减顺序排列的整数数组 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;
}
相关推荐
雨落在了我的手上1 小时前
Java数据结构(十四):Map和Set
数据结构
码行山野赴时序归途1 小时前
链表家族收官篇:循环链表
c语言·开发语言·数据结构·链表
别动我齐刘海1 小时前
ROS2 Jazzy + C++ 实战路线——进阶学习3
c++·人工智能·vscode·python·算法·机器学习·机器人
zhangfeng11332 小时前
《从“人工适配“到“智能生成“:KernelSwift 跨国产芯片算子迁移全栈方案解读》 —— 强调范式跃迁和跨硬件属性,适合偏架构分析的写法
人工智能·算法·华为·ai编程·npu
0+1112 小时前
算法 --滑动窗口
c++·算法·leetcode
reikocao2 小时前
大场景下 Hessian 特征值放大与退化检测
算法
hetao17338372 小时前
2026-09-18 hetao1733837 的刷题记录
c++·算法
wuyk5553 小时前
21.计数排序:不用比较的“空间换时间”排序算法
python·算法·排序算法
船厂电气自动化ai大模型3 小时前
AI大模型与数学|第81天 课程:正交向量、正交基、格拉姆‑施密特(Gram‑Schmidt)正交化
开发语言·数据结构·人工智能·线性代数·机器学习
Rabitebla3 小时前
【Linux系统编程】 指令(二):一条路径是怎么定位到文件的
linux·c++·笔记·学习·算法