原题:
Given a sorted array of integers, 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]
.
二分查找
代码1:
public int[] searchRange(int[] A, int target) {
int[] result = new int[2];
result[0] = -1;
result[1] = -1;
if(A==null || A.length<1) {
return result;
}
result[0] = findLeft(A, target);
result[1] = findRight(A, target);
return result;
}
private int findLeft(int[] A, int target) {
int result = 0;
int left = 0;
int right = A.length-1;
int middle;
while(left <= right) {
if( A[left]==target&&(left==0||A[left-1]!=target) ) {
return left;
}
middle = left + (right-left)/2;
if(A[middle]==target) {
if( (middle==0||A[middle-1]!=target) ) {
return middle;
} else {
right = middle-1;
}
} else if(A[middle]<target) {
left = middle+1;
} else {
right = middle-1;
}
}
return result;
}
private int findRight(int[] A, int target) {
int result = 0;
int left = 0;
int right = A.length-1;
int middle;
while(left <= right) {
if( A[right]==target&&(right==A.length-1 || A[right+1]!=target)) {
return result;
}
middle = left + (right-left)/2;
if(A[middle]==target) {
if( (middle==A.length-1||A[middle+1]!=target) ) {
return middle;
} else {
left = middle+1;
}
} else if(A[middle]<target) {
left = middle+1;
} else {
right = middle-1;
}
}
return result;
}
另一种写法:
public int[] searchRange(int[] A, int target) {
int[] result = new int[2];
result[0] = -1;
result[1] = -1;
if(A==null || A.length<1) {
return result;
}
int left = 0;
int right = A.length-1;
int middle;
while(left<=right) {
middle = left + (right-left)/2;
if(A[middle]<target) {
left = middle+1;
} else if(A[middle]>target) {
right = middle-1;
} else {
result[0] = lowerBound(A, left, middle-1, target);
result[1] = upperBound(A, middle+1, right, target);
return result;
}
}
return result;
}
private int lowerBound(int[] A, int left, int right, int target) {
while(left<=right) {
int middle = left + (right-left)/2;
if(A[middle]<target) {
left = middle+1;
} else {
right = middle-1;
}
}
return right+1;
}
private int upperBound(int[] A, int left, int right, int target) {
while(left<=right) {
int middle = left + (right-left)/2;
if(A[middle]<=target) {
left = middle+1;
} else {
right = middle-1;
}
}
return left-1;
}