题目
34. 在排序数组中查找元素的第一个和最后一个位置
https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/
题解
二分查找
先用二分查找找到目标值第一个所在的位置,然后再用二分查找,找到目标值最后一个所在位置。
第一个所在值的查找逻辑:
1 如果nums[mid] 等于 target:
- 如果mid左边一个位置的值等于value, 那么就
high = mid - 1
- 如果mid左边一个位置的值不等于value, 那么找到了,返回位置的坐标
2 如果nums[mid] 大于 target, 那么high = mid - 1
;
3 如果nums[mid] 小于 target, 那么low = mid + 1
最后一个所在值的查找逻辑:
1 如果nums[mid] 等于 target:
- 如果mid右边一个位置的值等于value, 那么就
low = mid + 1
- 如果mid右边一个位置的值不等于value, 那么找到了,返回位置的坐标
2 如果nums[mid] 大于 target, 那么 high = mid - 1
;
3 如果nums[mid] 小于 target, 那么 low = mid + 1
;
public int[] searchRange(int[] nums, int target) {
int[] ans = {-1, -1};
if (nums == null || nums.length == 0) {
return ans;
}
int low = 0;
int firstPosition = getFirstTarget(nums, target, nums.length);
int lastPosition = getLastTarget(nums, target, nums.length);
if (firstPosition == -1 && lastPosition == -1){
return ans;
} else if (firstPosition == -1) {
ans[0] = lastPosition;
ans[1] = lastPosition;
return ans;
} else if (lastPosition == -1){
ans[0] = firstPosition;
ans[1] = firstPosition;
} else if (firstPosition != -1 && lastPosition != -1){
ans[0] = firstPosition;
ans[1] = lastPosition;
return ans;
}
return ans;
}
private int getFirstTarget(int[] arr, int target, int len) {
int low = 0;
int high = len - 1;
while (low <= high) {
int mid = low + ((high - low) >> 1);
if (arr[mid] == target) {
if (mid == 0 || (mid > 0 && arr[mid - 1] != target)) {
return mid;
} else {
high = mid - 1;
}
} else if (arr[mid] > target) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return -1;
}
// 注意,这里的high的初始值是len,所以high的改变值的方式变了。
private int getLastTarget(int[] arr, int target, int len) {
int low = 0;
int high = len;
while (low < high) {
int mid = low + ((high - low) >> 1);
if (arr[mid] == target) {
if (mid == len - 1 || (mid < len - 1 && arr[mid] != arr[mid + 1])) {
return mid;
} else {
low = mid + 1;
}
} else if (arr[mid] > target) {
high = mid;
} else if (arr[mid] < target) {
low = mid + 1;
}
}
return -1;
}