34.在排序数组中查找元素的第一个和最后一个位置(力扣LeetCode)

文章目录

34.在排序数组中查找元素的第一个和最后一个位置

题目描述

给你一个按照非递减顺序排列的整数数组 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

提示:

  • 0 <= nums.length <= 105
  • -109 <= numsi <= 109
  • nums 是一个非递减数组
  • -109 <= target <= 109

二分

  这里有个坑,一个数组和vertor的坑,因为我平时习惯用数组,不会在意二分查找如果找不到的一个边界问题(数组开全局变量,初始化为零,并且我数组会开的很大,不会越界),但使用vector时一旦找不到会存在vector的访问越界

  • 以前使用数组时直接if(b[l] == a) return l;:
cpp 复制代码
int find1(int a)
{
    int l = 0, r = n - 1;
    while(l < r)
    {
        int mid = l + r >> 1;
        if(b[mid] >= a) r = mid;
        else l = mid + 1;
    }
    if(b[l] == a) return l;
    return -1;
}
  • 现在使用vector需要判断是否越界if (r < 0) return -1;:
cpp 复制代码
int find1(vector<int>& nums, int n)
    {
        int l=0,r=nums.size()-1;
        while(l<r)
        {
            int mid=l+r>>1;
            if(nums[mid]>=n) r=mid;
            else             l=mid+1;
        }
        if (r < 0) return -1;
        if (nums[r] == n) return r;
        return -1;
    }
cpp 复制代码
// 定义解决问题的类 Solution
class Solution {
public:
    // 主函数,用来查找目标值的开始和结束位置
    vector<int> searchRange(vector<int>& nums, int target) {
        // 初始化结果数组为 [-1, -1],表示目标值的开始和结束位置
        vector<int> num(2, -1);
        // 首先查找目标值的开始位置
        num[0] = find1(nums, target);
        // 如果开始位置为 -1,说明数组中没有目标值,直接返回 [-1, -1]
        if(num[0] == -1) return num;
        // 否则,查找目标值的结束位置
        else num[1] = find2(nums, target);
        // 返回包含开始和结束位置的数组
        return num;
    }

private:
    // 辅助函数 find1,用于查找目标值的开始位置
    int find1(vector<int>& nums, int n) {
        // 初始化二分查找的左右边界
        int l = 0, r = nums.size() - 1;
        while(l < r) {
            // 查找左中位数,因为我们在查找开始位置
            int mid = (l + r) >> 1;
            // 如果中间值大于等于目标值 n,我们将右边界移动到 mid
            if(nums[mid] >= n) r = mid;
            // 否则,将左边界移动到 mid + 1
            else l = mid + 1;
        }
        // 检查边界条件,确保 r 没有越界
        // 查找左边界时,r会一直逼近左边界,如果找不到r<0
        if (r < 0) return -1;
        // 如果 nums[r] 等于目标值 n,则 r 是开始位置
        if (nums[r] == n) return r;
        // 否则,说明数组中没有目标值,返回 -1
        return -1;
    }

    // 辅助函数 find2,用于查找目标值的结束位置
    int find2(vector<int>& nums, int n) {
        // 初始化二分查找的左右边界
        int l = 0, r = nums.size() - 1;
        while(l < r) {
            // 查找右中位数,因为我们在查找结束位置
            int mid = (l + r + 1) >> 1;
            // 如果中间值小于等于目标值 n,我们将左边界移动到 mid
            if(nums[mid] <= n) l = mid;
            // 否则,将右边界移动到 mid - 1
            else r = mid - 1;
        }
        // 检查边界条件,确保 l 没有越界
        // 查找右边界时,l会一直逼近右边界,如果找不到l>nums.size()-1(l >= nums.size())
        if (l >= nums.size()) return -1;
        // 如果 nums[l] 等于目标值 n,则 l 是结束位置
        if (nums[l] == n) return l;
        // 否则,说明数组中没有目标值,返回 -1
        return -1;
    }
};
相关推荐
mmmmath_310 小时前
二叉树の递归遍历
算法
All for pursuit.11 小时前
【位运算-1】338.比特位计数
数据结构·c++·算法·leetcode
小师兄吃牛肉11 小时前
C语言中的nullptr有必要吗
c语言·c++·算法
WL学习笔记12 小时前
日期类(C++)
开发语言·c++·日期类实现
H.莓飛13 小时前
【C++】命名空间、缺省参数、函数重载与引用
linux·开发语言·c++·visual studio
一只小小的芙厨13 小时前
【线性DP】
学习·算法·动态规划
xxwl58513 小时前
数据结构知识点和代码实现总结(C语言实现)
c语言·开发语言·数据结构
奋发向前wcx13 小时前
CSP-J复赛模拟赛5 王晨旭补题 2026.10.5
算法
汉克老师14 小时前
GESP2026年9月认证C++八级( 第一部分选择题(1~7题)精讲
c++·gesp·小学生·学c++编程
罗湖老棍子15 小时前
C Looooops(信息学奥赛一本通- P1640)
算法·数论·同余·裴蜀定理·扩展欧几里得