1. 题目描述:
Given an array of integers nums 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]
.
Example 1:
Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]
Example 2:
Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
2. 思路分析:
题目的意思是找 target 在有序数组 nums 中出现的最小下标和最大下标组成的数组。否则返回 {-1, -1}。要求时间复杂度为 O(log n)。
根据这个时间复杂度要求,首先想到的是用二分查找算法,这题虽然和二分查找不太一样,但是思路是一样的,可以先用二分查找找到,最左位置,然后继续用二分查找,找到最右位置即可。时间复杂度满足题目要求。
3. Java代码:
源代码
:见我GiHub主页
代码:
public int[] searchRange(int[] nums, int target) {
int[] result = {-1, -1};
int leftIndex = indexSearch(nums, target, true);
// 表示未找到target
if (leftIndex == nums.length || nums[leftIndex] != target) {
return result;
}
result[0] = leftIndex;
// 因为返回的是最右位置的下一个位置,需要进行减 1 操作
result[1] = indexSearch(nums, target, false) - 1;
return result;
}
/**
* 类似于二分查找,用于查找target对应数值的最左位置和最右位置的下一个位置
* isLeft 表示当次查找是最左位置,还是最右位置的下一个位置
*/
private int indexSearch(int[] nums, int target, boolean isLeft) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] == target && isLeft) { // 如果是查最左位置,则应继续在左半部分查找,否则在右半部分查找
right = mid - 1;
} else {
left = mid + 1;
}
}
return left;
}