LeetCode上的一道题目 https://leetcode.com/problems/search-for-a-range/?tab=Description
这个题目要求在O(log n)的复杂度内求出一个有序可重复数组中一个数字出现的起始和终止下标。
有序数组查找指定元素,首先想到的就是二分查找。
最基本的二分查找是用于无重复数字中指定数字出现的下标。
基本的二分查找是这样的
int start = 0, end = len-1;
while(start <= end){
int mid = (start+end) >> 1;
if(nums[mid] > target){
end = mid-1;
}
else if (nums[mid] < target){
start = mid + 1;
}
else{
return mid;
break;
}
}
而如果想要获得可重复数字数组中的第一个,可以变为
int idx = -1;
int start = 0, end = len-1;
while(start <= end){
int mid = (start+end) >> 1;
if(nums[mid] >= target){
end = mid-1;
}
else {
start = mid + 1;
}
if(nums[mid] == target){
idx = mid;
}
}
returm idx;
同理,可写出查找到在可重复数组中出现最后一次的方法。
因此该问题的一种解法为
public class Solution {
public int[] searchRange(int[] nums, int target) {
int len = nums.length;
int low = 0, high = len-1;
int start = -1, end = -1;
int[] res = {-1,-1};
int mid = (low+high) >> 1;
while(low <= high){
mid = (low+high) >> 1;
if(nums[mid] >= target){
high = mid-1;
}
else {
low = mid + 1;
}
if(nums[mid] == target){
start = mid;
}
}
if(start == -1){
return res;
}
low = start;
high = len-1;
while(low <= high){
mid = (low+high) >> 1;
if(nums[mid] > target){
high = mid-1;
}
else {
low = mid + 1;
}
if(nums[mid] == target){
end = mid;
}
}
res[0] = start;
res[1] = end;
return res;
}
}