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

题目

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

解析(查找问题用二分法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;
    }
}

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

你可能感兴趣的:(java,leetcode,算法)