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

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

问题描述:
  给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
  你的算法时间复杂度必须是 O(log n) 级别。
  如果数组中不存在目标值,返回 [-1, -1]。

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:41.9 MB, 在所有 Java 提交中击败了70.19%的用户

二分查找

  1. 使用二分查找,若mid不是target则向左、右二分
  2. (第一次出现位置)若mid恰好是target,且向左人为target,则将right设为mid-1继续二分
  3. 反之mid处即为第一次出现位置,返回该位置
  4. target最后一次出现位置搜索方式同上
class Solution {
    public int[] searchRange(int[] nums, int target) {
        /*边界情况*/
        if(nums==null || nums.length==0) 
            return new int[]{-1,-1};
        if(nums.length==1) 
            return nums[0]==target? new int[]{0,0}:
                        new int[]{-1,-1};
        /*改进的二分查找*/
        int[] ans = new int[2];
        Arrays.fill(ans, -1);
        int lIdx = 0, rIdx = nums.length-1;
        /*找到最左*/
        while(lIdx <= rIdx){
            int midIdx = lIdx + (rIdx-lIdx)/2;
            /*中间相等且左边相等*/
            if(nums[midIdx]==target)
                if(midIdx>lIdx && nums[midIdx-1]==target)
                    rIdx = midIdx-1;
                else{
                    ans[0] = midIdx;
                    break;
                }
            /*二分*/
            else if(nums[midIdx] > target)
                rIdx = midIdx-1;
            else
                lIdx = midIdx+1;
        }
        /*找到最右*/
        lIdx = 0; rIdx = nums.length-1;
        while(lIdx <= rIdx){
            int midIdx = lIdx + (rIdx-lIdx)/2;
            /*中间相等且右边相等*/
            if(nums[midIdx]==target)
                if(midIdx<rIdx && nums[midIdx+1]==target)
                    lIdx = midIdx+1;
                else{
                    ans[1] = midIdx;
                    break;
                }
            /*二分*/
            else if(nums[midIdx] > target)
                rIdx = midIdx-1;
            else
                lIdx = midIdx+1;
        }

        return ans;
    }
}
原文地址:https://www.cnblogs.com/CodeSPA/p/13684682.html