给定一个按照升序排列的整数数组 nums
,和一个目标值 target
。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]
。
示例 1:
输入: nums = [5,7,7,8,8,10]
, target = 8
输出: [3,4]
示例 2:
输入: nums = [5,7,7,8,8,10]
, target = 6
输出: [-1,-1]
这是一道比较难的模板理解的模板题目,这里先给一种区间划分解法
/*
* @lc app=leetcode.cn id=34 lang=java
*
* [34] 在排序数组中查找元素的第一个和最后一个位置
*/
class Solution {
public static int BinarySearch1(int[] nums, int target){
/*
这个代码划分的区间是[left,mid] [mid+1,right]
将mid划分在左边,可以找到左边第一次出现的mid
*/
int left = 0, right = nums.length - 1;
while(left<right){
int mid = left + (right-left)/2;
if(nums[mid]>=target) right = mid;
else left = mid+1;
}
if(nums[right]!=target) return -1;
else return right;
}
public static int BinarySearch2(int[] nums, int target){
/*
这个代码划分的区间是[left,mid-1] [mid,right]
将mid划分在左边,可以找到最后一次出现的mid
*/
int left = 0, right = nums.length - 1;
while(left<right){
int mid = 1+left + (right-left)/2; // 这里注意加1
if(nums[mid]<=target) left=mid;
else right = mid-1;
}
if(nums[right]!=target) return -1;
else return right;
}
public int[] searchRange(int[] nums, int target) {
if(nums==null || nums.length == 0) return new int[] {-1,-1};
int left = BinarySearch1(nums, target);
if(left==-1) return new int[] {-1,-1};
int right = BinarySearch2(nums, target);
return new int[] {left,right};
}
}