题目:在排序数组中查找元素的第一个和最后一个位置。给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。
我的答案:
思路:二分法
class Solution {
public int[] searchRange(int[] nums, int target) {
int low=0,high=nums.length-1,start=-1,end=-1;
while(low<=high){
int mid = (low + high)/2;
if(nums[mid]>target)
high = mid-1;
else if(nums[mid]<target)
low = mid+1;
else{ //找到符合条件的位置之后,在该位置向左向右寻找起始和结束的位置
int mid1=mid,mid2=mid;
while(mid1>=0 && nums[mid1]==target){
mid1--;
}
while(mid2<nums.length && nums[mid2]==target){
mid2++;
}
start=mid1+1;
end=mid2-1;
return new int[]{start,end};
}
}
return new int[]{start,end};
}
}
答案:
class Solution {
//二分查找,查找左索引时判断nums>=target,直至low=high;
//查找右索引时判断nums>target,直至low=high
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;
}
}