原题链接:34. Search for a Range
【思路-Java】非递归实现
主要考查二分查找,如果读者对二分查找不是很熟悉,这里推荐一篇博客:你真的会二分查找吗?,上面讲得非常详细。
本文主要实现两个方法:
1.searchRightIndex:查找并返回target出现在nums数组最右边的index。注意一点,如果target比数组最小值还小,那么返回-1
2.searchLeftIndex:查找并返回target出现在nums数组最左边的index。如果target比数组最大值还大,那么返回nums.length
仔细研读这两个方法,对深入理解二分查找十分有益:
public int[] searchRange(int[] nums, int target) {
int[] result = {-1, -1};
int index = searchRightIndex(nums, 0, nums.length - 1, target);
if (index < 0 || nums[index] != target)
return result;
result[0] = searchLeftIndex(nums, 0, index, target);
result[1] = index;
return result;
}
public int searchRightIndex(int[] nums, int left, int right, int target) {
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] > target) right = mid - 1;
else left = mid + 1;
}
return right;
}
public int searchLeftIndex(int[] nums, int left, int right, int target) {
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] < target) left = mid + 1;
else right = mid - 1;
}
return left;
}
81 / 81
test cases passed. Runtime: 1 ms Your runtime beats 6.97% of javasubmissions.
递归实现
public class Solution {
public int[] searchRange(int[] nums, int target) {
int[] res = new int[2];
res[0] = bSearchLeft(nums, target, 0, nums.length-1);
res[1] = bSearchRight(nums, target, 0, nums.length-1);
return res;
}
private int bSearchLeft(int[] nums, int target, int left, int right) {
if(left > right) return (left < nums.length && nums[left] == target) ? left : -1;
int mid = (left + right) / 2;
if(nums[mid] < target) return bSearchLeft(nums, target, mid+1, right);
else return bSearchLeft(nums, target, left, mid - 1);
}
private int bSearchRight(int[] nums, int target, int left, int right) {
if(left > right) return (right >= 0 && nums[right] == target) ? right : -1;
int mid = (left + right) / 2;
if(nums[mid] > target) return bSearchRight(nums, target, left, mid-1);
else return bSearchRight(nums, target, mid+1, right);
}
}
81 / 81
test cases passed. Runtime: 1 ms Your runtime beats 6.97% of javasubmissions.