算法题(138):在排序数组中查找元素的第一个和最后一个位置

发布于:2025-05-09 ⋅ 阅读:(21) ⋅ 点赞:(0)

审题:

本题需要我们找出非递减数组中target值的起始索引和终止索引,若没有target值就返回{-1,-1}

思路:
方法一:暴力搜索

我们可以利用双层for循环搜索所有子段,然后找到target的起始索引和终止索引。

不过他的时间复杂度就是O(n),不符合题目的要求

方法二:二分查找

由于本题的数组有一个不递减的特性,所以我们其实可以根据target值将数组划分为两个区域,一个区域是值小于等于target,另一个是大于target。这就是当前数组数据的二段性,根据这个二段性,我们可以使用二分算法

第一步:查找左边界

 1.进行前提:left < right

因为当left等于right的时候,说明我们要么找到了正确边界,要么该值不存在。若等于的情况都继续搜会出现死循环,后面我们详细分析

2.mid的求法:
由于这里我们求的是左边界,所以我们最终是要让right去靠近left的,所以要用

(left+right)/ 2来计算mid。

补充:

在right与left之差为偶数时,后面加的1不影响mid的结果

若是差为奇数,则加1会让mid偏右一位,不加会让mid偏左一位

这里我们的right和left的差为3,为奇数,所以我们加一之后得到的索引为2,不加得到的索引为1,这就是前面说的,加一会让mid偏右一位,不加会偏左一位

修正:图中应该使用索引3-0,而不是4-1,这里写错了

3.分类讨论:

当mid索引处的值大于等于target时,说明mid右边区域的值都可以从最小左边界中排除,让right指向mid索引的位置。

当mid索引处的值小于target时,说明mid左边的区域也可以排除,让left指向mid+1的位置

第二步:查找右边界

和左边界原理一致,注意点我们在代码区域讲解

解题:
(1)空数组处理
 

    if(nums.empty())//空数组情况
        return {-1,-1};

(2)查找左边界

int leftans = -1,rightans = -1;
//查找左边界
        int left = 0;
        int right = nums.size()-1;
        int mid = 0;
        while(left < right)
        {
            mid = (left+right)/2;
            if(nums[mid] >= target)
            {
             right = mid;
            }
            else
            {
               left = mid+1;
            }
        }
        if(nums[left] == target)
        leftans = left;
        else
        return {-1,-1};

注意:

1.当我们的left等于right后,还需要检查当前索引指向的值是否等于target值,若不等于说明数组中不存在target值,直接返回{-1,-1}

2.不让left等于right作为循环进行条件的原因:

若left等于right可以作为循环进行条件,那么我们要么会导致left>right,要么就陷入死循环(一直让right更新为mid,相当于没变),而陷入死循环是绝对不允许的

(3)查找右边界

//查找右边界
         left = 0;
         right = nums.size()-1;
         mid = 0;
        while(left < right)
        {
            mid = (left+right+1)/2;
            if(nums[mid] <= target)
            {
             left = mid;
            }
            else
            {
               right = mid-1;
            }
        }
  
        rightans = right;   
        return {leftans,rightans};

注意:

1.mid的计算需要加一:为了让left去靠近right

2.右边界不用检查值是否等于target:因为能进入到右边界搜索说明左边界一定存在,也就是target一定存在,所以右边界一定存在

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


网站公告

今日签到

点亮在社区的每一天
去签到