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 <= nums[i] <= 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;
    }
};
相关推荐
偷吃的耗子5 小时前
【CNN算法理解】:CNN平移不变性详解:数学原理与实例
人工智能·算法·cnn
坚果派·白晓明5 小时前
在鸿蒙设备上快速验证由lycium工具快速交叉编译的C/C++三方库
c语言·c++·harmonyos·鸿蒙·编程语言·openharmony·三方库
小镇敲码人5 小时前
深入剖析华为CANN框架下的Ops-CV仓库:从入门到实战指南
c++·python·华为·cann
dazzle5 小时前
机器学习算法原理与实践-入门(三):使用数学方法实现KNN
人工智能·算法·机器学习
那个村的李富贵5 小时前
智能炼金术:CANN加速的新材料AI设计系统
人工智能·算法·aigc·cann
张张努力变强6 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
万岳科技系统开发6 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
小镇敲码人6 小时前
探索CANN框架中TBE仓库:张量加速引擎的优化之道
c++·华为·acl·cann·ops-nn
wWYy.6 小时前
数组快排 链表归并
数据结构·链表
张登杰踩6 小时前
MCR ALS 多元曲线分辨算法详解
算法