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

题目:

给你一个按照非递减顺序排列的整数数组 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;
}
相关推荐
Liu628886 小时前
C++中的工厂模式高级应用
开发语言·c++·算法
AI科技星6 小时前
全尺度角速度统一:基于 v ≡ c 的纯推导与验证
c语言·开发语言·人工智能·opencv·算法·机器学习·数据挖掘
参.商.7 小时前
【Day41】143. 重排链表
leetcode·golang
条tiao条7 小时前
KMP 算法详解:告别暴力匹配,让字符串匹配 “永不回头”
开发语言·算法
干啥啥不行,秃头第一名7 小时前
C++20概念(Concepts)入门指南
开发语言·c++·算法
tobias.b7 小时前
计算机基础知识-数据结构
java·数据结构·考研
zzh940777 小时前
Gemini 3.1 Pro 硬核推理优化剖析:思维织锦、动态计算与国内实测
算法
2301_807367198 小时前
C++中的解释器模式变体
开发语言·c++·算法
愣头不青8 小时前
617.合并二叉树
java·算法
MIUMIUKK8 小时前
双指针三大例题
算法