LeetCode刷题之HOT100之在排序数组中查找元素的第一个和最后一个位置

下午雨变小了,但我并未去实验室,难得的一天呆在宿舍。有些无聊,看看这个,弄弄那个,听听歌,消磨时间。不知觉中时间指针蹦到了九点,做题啦!朋友推荐了 Eason 的 2010-DUO 演唱会,现在听着 live,敲着键盘。

1、题目描述

在这里插入图片描述

2、逻辑分析

题目要求很清晰,递增数组中,给定目标值,找到它的起始位置和结束位置。我的思路是这样的:
首先遍历数组,找到第一个与目标值相等的元素,再继续遍历,找到第一个与目标元素不相等的元素,比如[5,7,7,8,8,10]中,我们要找8的第一个和最后一个位置,那么我们先遍历,找到第一个8,位置索引是3;再继续遍历,找到第一个不等于8的元素10,那么我们需要的数的位置索引就是5 - 1 = 4,由于题目要求了时间复杂度O(logn),所以选择二分查找即可满足需求(其实我没有第一时间想到二分,是敲不出来后看题解才知道滴)。下面看代码演示

3、代码演示


```java
public int[] searchRange(int[] nums, int target) {
        // 调用binarySearch方法,搜索target的左边界(即第一次出现的位置)
        int leftId = binarySearch(nums, target, true);
        // 调用binarySearch方法,搜索target的右边界(即最后一次出现的位置的下一个索引,然后减1)
        int rightId = binarySearch(nums, target, false )- 1;
        // 检查左边界是否小于等于右边界,并且右边界没有越界,以及左右边界对应的值都等于target
        if(leftId <= rightId && rightId < nums.length && nums[leftId] == target && nums[rightId] == target){
            // 如果满足条件,返回左右边界的索引数组
            return new int []{leftId, rightId};
        }else{
            // 如果不满足条件,返回[-1, -1]表示没有找到target
            return new int []{-1, -1};
        }
    }
    // 二分查找函数,这里引入boolean类型是为了提高复用
    public int binarySearch(int[] nums, int target, boolean check ){
        // 初始化左右指针和答案变量为数组长度
        int left = 0, right = nums.length -1, ans = nums.length;
        // 当左指针小于等于右指针时继续搜索
        while(left <= right){
            int mid = (left + right)/ 2;
            // 如果中间值大于target,或者(当check为true时且中间值大于等于target)
            if(nums[mid] > target || (check && nums[mid] >= target)){
                // 更新答案为当前中间索引
                ans = mid;
                // 将搜索范围缩小到左半部分
                right = mid - 1;
            }else{
                // 将搜索范围缩小到右半部分
                left = mid + 1;
            }
        }
        // 返回最终的答案(左边界或右边界)
        return ans;
    }

在binarySearch方法中,ans的初始值被设置为nums.length。这是为了确保当目标值大于数组中的所有值时,我们仍然能够返回一个有效的索引(即数组的末尾之后的位置)。
同时,当 check 为 true 时,我们使用 >= 来确保找到的是目标值的第一个出现位置;当 check 为false 时,我们使用 > 来确保找到的是目标值最后出现位置的下一个索引。
最后该算法的时间复杂度:O(logn),空间复杂度:O(1)。

ok啦,雨停了,该去跑六月的第一次步啦,拜拜啦!

  • 15
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值