「这是我参与11月更文挑战的第20,活动详情查看:2021最后一次更文挑战」
题目描述
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-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]
- 示例3
输入:nums = [], target = 0
输出:[-1,-1]
- 进阶
- 你可以设计并实现时间复杂度为
O(log n)
的算法解决此问题吗?
- 提示:
- 0 <= nums.length <= 105
- -109 <= nums[i] <= 109
- nums 是一个非递减数组
- -109 <= target <= 109
题目分析
首先两次二分拿到下界和上界下标,若要找下界,则每次二分前判断当前nums[start]是否等于target,若要找上界,则每次二分前判断当前nums[end]是否等于target;
若在二分时发现nums[mid] = target,记录mid下标给idx,若 当前要找下界,则令end = mid - 1, 即继续找可能存在的更小的下标;否则令start = mid + 1,即继续找可能存在的更大的下标。
class Solution {
public int[] searchRange(int[] nums, int target) {
int start_idx = binarySearch(nums, 0, nums.length - 1, target, true);
if(start_idx == -1){
return new int[]{-1, -1};
}
int upper_idx = binarySearch(nums, 0, nums.length - 1, target, false);
return new int[]{start_idx, upper_idx};
}
public int binarySearch(int[] nums, int start, int end, int target, boolean isLower){
int idx = -1;
while(start <= end){
if(nums[start] == target && isLower){
return start;
}
if(nums[end] == target && !isLower){
return end;
}
int mid = (start + end) / 2;
if(nums[mid] < target){
start = mid + 1;
}else if(nums[mid] > target){
end = mid - 1;
}else{
idx = mid;
if(isLower){
end = mid - 1;
}else{
start = mid + 1;
}
}
}
return idx;
}
}
复制代码