leetcode第34题排序数组中查找指定元素出现的第一个和最后一个位置

题目

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

你的算法时间复杂度必须是 O(log n) 级别。

如果数组中不存在目标值,返回 [-1, -1]。

示例

输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]

题解

 题目采用二分查找思路进行求解,要定位目标值出现的开始结束位置可以转换为寻找左侧边界的二分查找问题,开始位置就是所求的左侧边界;右侧边界的查找可以利用同样的方法,让目标值加一然后再进行左侧边界查找,找到后的索引减一就是原始目标值出现的右侧边界。右侧边界的查找同样可以转换为寻找右侧边界的二分查找问题。

class Solution {
/*
 需要注意的是,编写左侧二分查找代码时,right取值要为nums.length,如果取值nums.length - 1的话,当查找数组最后一个数字时会出现index2-1之后结果小1,例如
nums = [5,7,7,8,8,10], target = 10,
返回[5,4]
出现这样的结果是因为right取值的上限为5,最后减一返回不正确
*/
    public int[] searchRange(int[] nums, int target) {
        int index1 = binarySearch(nums, target);    //寻找左侧边界
        int index2 = binarySearch(nums, target + 1);    //寻找右侧边界,真正的右侧边界还得是 index2 - 1
        if(index1 == nums.length || nums[index1] != target){
            return new int[]{-1, -1};
        }
        else{
            return new int[]{index1, index2 - 1};
        }
    }
    
    private int binarySearch(int[] nums, int target){
        int left = 0;
        int right = nums.length;    //注意这里要能取到边界值,不然当目标为最后一个值时会出现访问出错
        while(left < right){
            int mid = left + (right - left) / 2;
            if(nums[mid] < target){
                left = mid + 1;
            }
            else{
                right = mid;
            }
        }
        return right;
    }
}
原文地址:https://www.cnblogs.com/jianglinliu/p/11798482.html