Given an array of integers sorted in ascending order, find the starting and ending position of a given target value.
Your algorithm's runtime complexity must be in the order of O(log n).
If the target is not found in the array, return [-1, -1]
.
For example,
Given [5, 7, 7, 8, 8, 10]
and target value 8,
return [3, 4]
.
这是一道典型的二分搜索问题,如果依次向后搜索时间复杂度就是O(n),但是题目要求O(log n)的复杂度.所以要使用二分搜索。
但是这里涉及到怎么区分左边的和右边的搜索。我的做法:
左边位置:比较mid=(i+j)/2处的值和target的大小,如果num[mid]>=target就把右边界移动到mid,否则移动左边界。循环结束条件是还剩下三个数的时候。此时从左往右依次比较是否和target相等,相等的就是左边界。
右边位置:比较mid=(i+j)/2处的值和target的大小,如果num[mid]<=target就把左边界移动到mid,否则移动右边界。循环结束条件是还剩下三个数的时候。此时从右往左依次比较是否和target相等,相等的就是右边界。
class Solution {
public static int[] searchRange(int[] nums, int target) {
int[] result = new int[2];
if(nums.length==0){
result[0] = -1;
result[1] = -1;
return result;
}
int start = 0;
int end = nums.length - 1;
while(start<end-1){
int mid = (start+end)/2;
if(nums[mid]>=target){
end = mid;
}
else
start = mid;
}
if(nums[start]==target)
result[0]=start;
else if(nums[(start+end)/2]==target)
result[0] = (start+end)/2;
else if(nums[end]==target)
result[0] = end;
else
return new int[]{-1,-1};
start = 0;
end = nums.length - 1;
while(start<end-1){
int mid = (start+end)/2;
if(nums[mid]==target){
result[1] = mid;
start = mid;
}
else if(nums[mid]<target){
start = mid;
}
else
end = mid;
}
if(nums[end]==target)
result[1]=end;
else if(nums[(start+end)/2]==target)
result[1] = (start+end)/2;
else if(nums[start]==target)
result[1] = start;
return result;
}
}
但是其实这样做比较麻烦,参考方法:
不同之处主要是循环判断条件以及更新方式:左边位置的循环中i=mid+1导致可以自己结束循环。右边位置的循环中由于不能自己结束循环就把mid=(i+j)/2+1,也就是每次向右偏,那么最后也会自动终止循环。
public static int[] searchRange(int[] num, int target){
int[] result = new int[2];
if(num.length==0)
return new int[]{-1,-1};
int i=0, j = num.length;
while(i<j){
int mid = (i+j)/2;
if(num[mid]>=target)
j = mid;
else
i = mid+1;
}
if(num[i]==target)
result[0] = i;
else
return new int[]{-1,-1};
j = num.length;
while(i<j){
int mid = (i+j)/2+1;
if(num[mid]<=target)
i = mid;
else
j = mid-1;
}
if(num[j]==target)
result[1] = j;
return result;
}
//静态初始化数组:方法一
String cats[] = new String[] {
"Tom","Sam","Mimi"
};
//静态初始化数组:方法二
String dogs[] = {"Jimmy","Gougou","Doggy"};
//动态初始化数据
String books[] = new String[2];
books[0] = "Thinking in Java";
books[1] = "Effective Java";