题目: 给定一个按照升序排列的整数数组nums,和一个目标值target;找出给定目标值在数组中的开始位置和结束位置;
你的算法时间复杂度必须是 O(log n) 级别;
如果数组中不存在目标值,返回 [-1, -1];
示例 1:
输入: nums = [5,7,7,8,8,10],
输出: [3,4]
示例2:
输入: nums = [5,7,7,8,8,10],
输出: [-1,-1]
1.二分查找:
[1]思路:
(1)使用正常的二分搜索找到数组中一个等于目标值的元素;
(2)在满足等于目标值的条件语句中,
1)使用一个二分查找向左侧查找与目标值相等的下标: 特殊之处在于找到了继续向左查找,直到没有了;
2)使用一个二分查找向右侧查找与目标值相等的下标: 特殊之处在于找到了继续向右查找,直到没有了;
[2]实现:
class Solution {
public int[] searchRange(int[] nums, int target) {
int len = nums.length;
int left = 0, right = len - 1;
// 进行二分搜索
while (left <= right) {
int mid = (left + right) / 2;
if(nums[mid] == target){
// 使用二分搜索不断往左搜索,返回与目标值相等且最左的下标
int l = binarySearch(nums,0,mid,target,true);
// 使用二分搜索不断往有搜索,返回与目标值相等且最右的下标
int r = binarySearch(nums,mid,len - 1,target,false);
return new int[]{l,r};
}
if(nums[mid]>target){
right = mid-1;
}else if(nums[mid]<target){
left = mid +1;
}
}
return new int[]{-1,-1};
}
public int binarySearch(int[] nums,int start,int end,int target,boolean toLeft){
int left = start,right= end;
int preIndex = -1;
while (left <= right){
int mid = (left + right) / 2;
if(nums[mid] == target){
preIndex = mid;
if(toLeft){
right = mid -1;
}else {
left = mid +1;
}
}
if(nums[mid]>target){
right = mid-1;
}else if(nums[mid]<target){
left = mid +1;
}
}
return preIndex;
}
}
[3]复杂度分析:
(1)时间复杂度: O(logN),N为数组的长度
(2)空间复杂度: O(1)