1、题目
给定一个按照升序排列的整数数组 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 <= 105
-109 <= nums[i] <= 109
nums
是一个非递减数组-109 <= target <= 109
2、解题思路
(1)解决方案一:暴力破解;遍历两个指针记录起始位置和终止位置(时间复杂度为o(n),空间复杂度为o(1))
(2)解决方案二:二分查找;把问题转化成找两个指标:找到第一个等于目标值的位置,找到最后一个等于目标值的位置;(具体可以看代码里面的解释哈)
3、java代码
public static int[] searchRange(int[] nums, int target) {
int[] res=new int[]{-1,-1}; //定义一个初始的返回数组
if(nums==null || nums.length<1) return res; //判空
int left=searchIndex(nums,target,true); //先找第一个位置
if(left==-1){return res;} //如果不存在则直接返回默认结果
int right=searchIndex(nums,target,false); //找最后一个位置
res[0]=left;
res[1]=right;
return res; //找到之后把左右位置都赋值给结果数组,并返回
}
//定义一个找下标的方法
public static int searchIndex(int[] nums, int target,boolean if_first) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left+(right-left)/2; //这里这么写是为了防止整型越界
if (nums[mid] < target) { //如果中间值比目标值小,说明目标值在右边
left = mid + 1;
} else if (nums[mid] > target) { //如果中间值比目标值大,说明目标值在左边
right = mid - 1;
} else if (if_first && nums[mid]==target){ //如果是找第一个坐标,当跟目标值相等时,判断左边还有木有相等的
if (mid == 0 || nums[mid - 1] != target) {
return mid;
} else if (nums[mid - 1] == target) {
right = mid-1;
}
}else if (!if_first && nums[mid]==target){ //如果是找第二个坐标,当跟目标值相等时,判断右边还有木有相等的
if (mid == nums.length-1 || nums[mid + 1] != target) {
return mid;
} else if (nums[mid + 1] == target) {
left = mid+1;
}
}
}
return -1;
}