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].
这道题感觉代码写的很烂 下次看看还可不可以写的好看一点。老师的解法要好很多
下面这个解法 如果重复数据很多,就变成了线性搜索了。所以应该利用 binary search 来查找 左右边界
public class Solution {
public int[] searchRange(int[] A, int target) {
int[] res = {-1, -1};
if (A == null || A.length == 0) {
return res;
}
int start = 0;
int end = A.length - 1;
int mid;
int t1 = -1;
int t2 = -1;
while (end - start > 1) {
mid = start + (end - start)/2;
if (A[mid] == target) {
for (t1 = mid - 1; t1 >= 0; t1--) {
if (A[t1] != target) {
break;
}
}
for (t2 = mid + 1; t2 < A.length; t2++) {
if (A[t2] != target) {
break;
}
}
res[0] = t1 + 1;
res[1] = t2 - 1;
return res;
} else if (A[mid] < target) {
start = mid + 1;
} else {
end = mid - 1;
}
}
if ((target == A[start]) && (target == A[end])){
t1 = start;
t2 = end;
} else if ((target == A[start]) && (target != A[end])){
t1 = start;
t2 = start;
} else if ((target != A[start]) && (target == A[end])){
t1 = end;
t2 = end;
}
res[0] = t1;
res[1] = t2;
return res;
}
}下面这种情况 时间复杂度就可以保证 logn 了
public class Solution {
public int[] searchRange(int[] A, int target) {
int[] res = {-1, -1};
if (A == null || A.length == 0) {
return res;
}
int start = 0;
int end = A.length - 1;
int mid;
int low = -1;
int high = -1;
//search for left bound
while (end - start > 1) {
mid = start + (end - start)/2;
if (A[mid] == target) {
end = mid;
} else if (A[mid] < target) {
start = mid + 1;
} else {
end = mid - 1;
}
}
if (target == A[start]) {
low = start;
} else if (target == A[end]) {
low = end;
}
//search for right bound
start = 0;
end = A.length - 1;
while (end - start > 1) {
mid = start + (end - start)/2;
if (A[mid] == target) {
start = mid;
} else if (A[mid] < target) {
start = mid + 1;
} else {
end = mid - 1;
}
}
if (target == A[end]) {
high = end;
} else if (target == A[start]) {
high = start;
}
res[0] = low;
res[1] = high;
return res;
}
}
第二次写的实现方法;
先找到一个,然后在这个点的左右进行搜索
public class Solution {
public int[] searchRange(int[] A, int target) {
if (A == null) {
return null;
}
int[] result = new int[2];
int left = binarySearch(A, 0, A.length - 1, target);
int right = left;
while ((left - 1) >= 0) {
int leftEnd = binarySearch(A, 0, left - 1, target);
if (leftEnd == -1) {
break;
}
left = leftEnd;
}
while ((right + 1) < A.length) {
int rightEnd = binarySearch(A, right + 1, A.length - 1, target);
if (rightEnd == -1) {
break;
}
right = rightEnd;
}
result[0] = left;
result[1] = right;
return result;
}
private int binarySearch(int[] A, int start, int end, int target) {
while(start <= end) {
int mid = start + (end - start) / 2;
if (target == A[mid]) {
return mid;
} else if (target < A[mid]) {
end = mid - 1;
} else {
start = mid + 1;
}
}
return -1;
}
}
本文介绍了如何使用改进的二分查找算法在有序数组中高效地查找目标值的起始和结束位置。通过两次二分查找分别定位目标值的左边界和右边界,确保时间复杂度为O(log n)。同时,提供了两种实现方法,第一种方法在遇到重复元素时可能退化为线性搜索,第二种方法则充分利用了二分查找的特性,有效避免了这一问题。
3251

被折叠的 条评论
为什么被折叠?



