给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解、数组有序,用二分法查找,时间复杂度O(log n)
特殊情况数组长度为0,直接返回。
第一个为target的数值即用nums[mid]>= target,看是否有相等,有的话即为第一个等于target的数值
找target的左边界,让他落在nums[mid]左侧作为首选条件,可将范围分割为两部分,确定是否包含左边界。
①如果target位于nums[mid]的左边(nums[mid] >= target),再次搜索时可向左推进,right = mid;
②如果target位于nums[mid]的右侧(nums[mid] < target),说明左边界得向右推移,left = mid+ 1。
③若最终返回值不为target,直接返回[-1, -1];
第末个为target的数值急用nums[mid]<= targe,前一个若有相等,此时这个必有,即可返回。
找target的右边界,让他落在nums[mid]右则作为首选条件,之后else分析另一侧。
①如果target位于nums[mid]的右边(nums[mid]<= target),说明左边界向右推进,left = mid;
②如果target位于nums[mid]的左边(nums[mid] > target),更新右边界搜索target,right = mid -1。
- class Solution{
- public int[] searchRange(int[] nums, int target){
- int len = nums.length;
- if(len == 0) return new int[]{-1, -1};
- int left = 0, right = len - 1;
- while(left < right){
- int mid = left + (right - left) / 2;
- if(nums[mid] >= target){
- right = mid;
- }else{
- left = mid + 1;
- }
- }
- if(nums[right] != target) return new int[]{-1, -1};
- int L = right;
- left = 0;
- right = len - 1;
- while(left < right){
- int mid = left + (right - left + 1) / 2;
- if(nums[mid] <= target){
- left = mid;
- }else{
- right = mid - 1;
- }
- }
- return new int[]{L, right};
- }
- }