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

发布于 2024-06-09  9 次阅读


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

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

你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

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

输出:[3,4]

示例 2:

输入:nums = [5,7,7,8,8,10], target = 6

输出:[-1,-1]

示例 3:

输入:nums = [], target = 0

输出:[-1,-1]

思路:可以遍历一遍数组,记录第一次出现target的位置和最后出现的位置,但时间复杂度为O(n)。

使用2次二分查找,第一次二分查找找到first位置,这里要在nums[mid] = target 时令 right = mid - 1,继续往左查找寻找可能的first位置。第二次二分查找找到last位置,这里要在nums[mid] = target 时令 left = mid + 1,继续往右查找寻找可能的last位置

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int first = -1, last = -1;
        int left = 0, right = nums.length - 1;
        while(left <= right){
            int mid = (left + right) / 2;
            if(nums[mid] == target){
                first = mid;
                right = mid - 1;
            }else if(nums[mid] < target){
                left = mid + 1;
            }else{
                right = mid - 1;
            }
        }

        left = 0;
        right = nums.length - 1;

        while(left <= right){
            int mid = (left + right) / 2;
            if(nums[mid] == target){
                last = mid;
                left = mid + 1;
            }else if(nums[mid] < target){
                left = mid + 1;
            }else{
                right = mid - 1;
            }
        }
        return new int[]{first, last};
    }
}