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

简介: 二分查找是一种高效的查找算法,其时间复杂度为 O(log n)。在许多情况下,我们需要在一个有序数组中找到某个目标值的搜索范围。本文将介绍一种基于二分查找的搜索范围查找算法,该算法能够快速找到目标值在数组中的起始和结束位置。

前言

二分查找是一种高效的查找算法,其时间复杂度为 O(log n)。在许多情况下,我们需要在一个有序数组中找到某个目标值的搜索范围。本文将介绍一种基于二分查找的搜索范围查找算法,该算法能够快速找到目标值在数组中的起始和结束位置。

在另一篇博客里讲过二分法的模板:

《二分法的模板讲解》


🕺作者: 迷茫的启明星


学习路线

C语言从0到1

C++初阶

数据结构从0到1

😘欢迎关注:👍点赞🙌收藏✍️留言


🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要,有问题可在评论区提出,感谢阅读!!!


问题描述

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


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


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


解题思路

该算法的核心思想是在二分查找的基础上进行修改,以实现搜索范围的查找。具体来说,我们需要实现两个辅助函数:binarySearchLeft 和 binarySearchRight,分别用于查找目标值在数组中的左边界和右边界。


binarySearchLeft

binarySearchLeft 函数的实现思路与二分查找类似,但在判断条件上略有不同。当 nums[mid] >= target 时,我们更新右边界 r = mid,以便在下一次迭代时继续搜索左侧区域。这样,当循环结束时,l 指针所指向的位置即为目标值的左边界。


binarySearchRight

binarySearchRight 函数的实现思路与 binarySearchLeft 类似,但在判断条件上略有不同。当 nums[mid] <= target 时,我们更新左边界 l = mid,以便在下一次迭代时继续搜索右侧区域。这样,当循环结束时,r 指针所指向的位置即为目标值的右边界。


searchRange

searchRange 函数是主函数,用于接收目标值,并调用 binarySearchLeft 和 binarySearchRight 函数找到目标值的左边界和右边界。如果找到的左边界和右边界满足条件(leftIdx <= rightIdx && rightIdx<nums.size() && nums[leftIdx]==target && nums[rightIdx]==target),则返回目标值的搜索范围,否则返回 -1。


代码

class Solution {
public:
    int binarySearchLeft(vector<int>& nums, int target) {
        int l=-1, r=(int)nums.size();
        while (l+1!=r) {
            int mid = l+(r-l)/2;
            if(nums[mid]>=target) {
                r = mid;
            } else {
                l = mid;
            }
        }
        return r;
    }
    int binarySearchRight(vector<int>& nums, int target) {
        int l=-1, r=(int)nums.size();
        while (l+1!=r) {
            int mid = l+(r-l)/2;
            if(nums[mid]<=target) {
                l = mid;
            } else {
                r = mid;
            }
        }
        return l;
    }
    vector<int> searchRange(vector<int>& nums, int target) {
        int leftIdx = binarySearchLeft(nums, target);
        int rightIdx = binarySearchRight(nums, target);
        if(leftIdx<=rightIdx && rightIdx<nums.size() && nums[leftIdx]==target && nums[rightIdx]==target) {
            return {leftIdx, rightIdx};
        }
        return {-1, -1};
    }
};




结论

基于二分查找的搜索范围查找算法具有高效性,时间复杂度为 O(log n)。在实际应用中,它可以帮助我们快速找到目标值在数组中的搜索范围,为后续操作提供便利。


本文由mdnice多平台发布


相关文章
|
3月前
|
算法
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
|
3月前
|
算法 索引
LeetCode第34题在排序数组中查找元素的第一个和最后一个位置
这篇文章介绍了LeetCode第34题"在排序数组中查找元素的第一个和最后一个位置"的解题方法,通过使用双指针法从数组两端向中间同时查找目标值,有效地找到了目标值的首次和最后一次出现的索引位置。
LeetCode第34题在排序数组中查找元素的第一个和最后一个位置
|
6月前
在排序数组中查找元素的第一个和最后一个位置
在排序数组中查找元素的第一个和最后一个位置
|
6月前
|
算法
leetcode-34:在排序数组中查找元素的第一个和最后一个位置
leetcode-34:在排序数组中查找元素的第一个和最后一个位置
33 0
|
算法
【算法专题突破】二分查找 - 在排序数组中查找元素的第一个和最后一个位置(17)
【算法专题突破】二分查找 - 在排序数组中查找元素的第一个和最后一个位置(17)
63 0
LeetCode-34 在排序数组中查找元素的第一个和最后一个位置
LeetCode-34 在排序数组中查找元素的第一个和最后一个位置
|
算法 安全 Swift
LeetCode - #34 在排序数组中查找元素的第一个和最后一个位置(Top 100)
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
|
算法
每日一题—— 在排序数组中查找元素的第一个和最后一个位置
每日一题—— 在排序数组中查找元素的第一个和最后一个位置
|
算法
力扣34题. 在排序数组中查找元素的第一个和最后一个位置
力扣34题. 在排序数组中查找元素的第一个和最后一个位置
84 0
|
算法
LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置
LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置
108 0
LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置