给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
今天和我一起实习的老哥面字节被问到了,这个题属于二分法的变种,听起来挺简单,但是要写出来最优解也是需要功底的。
logn的时间复杂度,说明肯定2分法,不能单纯的2分找到一个target然后向两边进行线性搜素,因为这样就无法保证logn的复杂度了,只能这样:一次二分找最左边也就是第一次出现的target,一次二分找最右边也就是最后一次出现的target。但是找左边界和右边界方法是不一样的。代码如下,边界条件是需要注意的!!!
class Solution {
public int[] searchRange(int[] nums, int target) {
int left =left_search(nums,target);
int right =right_search(nums,target);
return new int[]{left,right};
}
//搜索左边界
public int left_search(int[] nums, int target){
int left =0,right =nums.length;
while(right>left){
int mid =(left+right)/2;
if(nums[mid]==target){
right = mid;
}
else if(nums[mid]<target){
left = mid + 1;
}
else if(nums[mid]>target){
right = mid;
}
}
//判断越界情况
if(left==nums.length||nums[left]!=target) return -1;
return left;
}
//搜索右边界
public int right_search(int[] nums, int target){
int left =0,right =nums.length;
while(right>left){
int mid =(left+right)/2;
if(nums[mid]==target){
left= mid+1;
}
else if(nums[mid]<target){
left = mid + 1;
}
else if(nums[mid]>target){
right = mid;
}
}
//判断越界情况
if(right==0||nums[right-1]!=target) return -1;
return right-1;
}
}