LeetCode Hot 100 --- 在排序数组中查找元素的第一个和最后一个位置(java)

题目

在这里插入图片描述

解析(查找问题用二分法yyds)

由于数组已经排序,因此整个数组是单调递增的,我们可以利用二分法来加速查找的过程。

考虑 target 开始和结束位置,其实我们要找的就是数组中第一个>=target 的位置(记为 leftIdx)和第一个>target 的位置减一(记为rightIdx),如nums = [5,7,7,8,8,10],target = 8,下标leftIdx=3,rightIdx=5-1=4。为了代码的复用,我们定义 binarySearch(nums, target, flag),flag=true表示>=target,flag=false表示>target,最后需要检验leftIdx和rightIdx,因为查找时可能会导致下标值不属于数组下标[0,nums.length-1]这个范围

class Solution {
    public int[] searchRange(int[] nums, int target) {
        //判空
        if(nums == null || nums.length == 0){
            return new int[]{-1,-1};
        }
        //二分查找
        int leftIdx = binarySearch(nums,target,true);//>=
        int rightIdx = binarySearch(nums,target,false) - 1;//>
        //leftIdx肯定>=0,因为left > right跳出,mid最小=0,res=mid,而leftIdx会得到res,所以肯定也>=0
        //同理rightIdx也肯定<=nums.length - 1,因为返回的res最大才nums.length
        //这里为什么要做检查?leftIdx <= rightIdx 是保证不索引越界,开始位置肯定要<=结束位置
        //而做nums[leftIdx] == target && nums[rightIdx] == target因为[1,2,5],target=4情况
        //最后res返回1,也就是nums[1]=2,但是2!=4,元素根本不存在
        if(leftIdx <= rightIdx && nums[leftIdx] == target && nums[rightIdx] == target){
            return new int[]{leftIdx,rightIdx};
        }
        return new int[]{-1,-1};
    }
    private int binarySearch(int[] nums, int target, boolean flag){
        int left = 0,right = nums.length - 1,res = nums.length;
        while(left <= right){
            int mid = (left + right) / 2;
            // >=和>两种情况合并
            if((flag && nums[mid] >= target) || nums[mid] > target){
                right = mid - 1;//target在mid左边,要变小
                res = mid;//这句自己用题目示例按代码写一遍即可知道,很重要
            }else{
                left = mid + 1;//target在mid右边,要变大
            }
        }
        return res;
    }
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小样x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值