LeetCode No34. 在排序数组中查找元素的第一个和最后一个位置
题目
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
进阶:
你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2:
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
示例 3:
输入:nums = [], target = 0
输出:[-1,-1]
提示:
0 <= nums.length <= 10^5
-10^9 <= nums[i] <= 10^9
nums 是一个非递减数组
-10^9 <= target <= 10^9
思路
暴力解法就不写了,for循环从头/尾遍历即可。而进阶的解法,看到有序数组找某个值对应的下标,第一反应就是二分查找,而这个题目比较特别,要求找第一个位置low和最后一个位置high,但是换个思路,low其实就是求第一个大于等于target的下标,而high就是求第一个小于等于target的下标,然后我们只要检查这两个下标是否满足 low<=high ,如果不满足,说明数组没有等于target的值,返回 [-1,-1]。
AC代码
点击查看代码
class Solution {
private int b_search_low(int[] nums, int low, int high, int target) {
while( low <= high ) {
int mid = (low+high)/2;
if( nums[mid]>=target) {
high = mid -1;
} else {
low = mid+1;
}
}
return low;
}
private int b_search_high(int[] nums, int low, int high, int target) {
while( low <= high ) {
int mid = (low+high)/2;
if( nums[mid]<=target) {
low = mid +1;
} else {
high = mid - 1 ;
}
}
return high;
}
public int[] searchRange(int[] nums, int target) {
int len = nums.length;
if( nums.length == 0) {
return new int[]{-1, -1};
}
int low = b_search_low(nums, 0, len-1, target);
int high = b_search_high(nums, 0, len-1, target);
if( low>high ) {
return new int[]{-1, -1};
}
return new int[]{low, high};
}
}
低调做人,高调做事。