给定一个按照升序排列的整数数组 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]
1.不符合题目要求的正确解法:
直接硬解,也就是线性解法,但是时间复杂度不符合O(log n)要求
2.分别计算出左边界和右边界
class Solution {
public int[] searchRange(int[] nums, int target) {
int leftIndex = findLeftRange(nums,target);
int rightIndex = findRightRange(nums,target);
return new int[]{leftIndex,rightIndex};
}
public int findLeftRange(int[] nums, int target){
int L = 0;
int R = nums.length;
while(L<R){
int mid = (L+R)/2;
if(nums[mid]==target){
R=mid;
}else if(nums[mid]>target){
R=mid;
}else if(nums[mid]<target){
L=mid+1;
}
}
if(L==nums.length){
return -1;
}else if(nums[L]==target){
return L;
}else{
return -1;
}
}
public int findRightRange(int[] nums, int target){
int L = 0;
int R = nums.length;
while(L<R){
int mid = (L+R)/2;
if(nums[mid]==target){
L=mid+1;
}else if(nums[mid]>target){
R=mid;
}else if(nums[mid]<target){
L=mid+1;
}
}
if(L==0){
return -1;
}else if(nums[L-1]==target){
return L-1;
}else{
return -1;
}
}
}
这里有一篇很好的解释二分算法的文章,可以参考:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/er-fen-cha-zhao-suan-fa-xi-jie-xiang-jie-by-labula/
3.官方解法
官方解法其实和上面的找出左右界限是一样的,只是进行了代码整合
class Solution {
// returns leftmost (or rightmost) index at which `target` should be
// inserted in sorted array `nums` via binary search.
private int extremeInsertionIndex(int[] nums, int target, boolean left) {
int lo = 0;
int hi = nums.length;
while (lo < hi) {
int mid = (lo + hi) / 2;
if (nums[mid] > target || (left && target == nums[mid])) {
hi = mid;
}
else {
lo = mid+1;
}
}
return lo;
}
public int[] searchRange(int[] nums, int target) {
int[] targetRange = {-1, -1};
int leftIdx = extremeInsertionIndex(nums, target, true);
// assert that `leftIdx` is within the array bounds and that `target`
// is actually in `nums`.
if (leftIdx == nums.length || nums[leftIdx] != target) {
return targetRange;
}
targetRange[0] = leftIdx;
targetRange[1] = extremeInsertionIndex(nums, target, false)-1;
return targetRange;
}
}