題目
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;
}