力扣第34题:
在排序数组中查找元素的第一个和最后一个位置
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1, -1]。
进阶:
- 你可以设计并实现时间复杂度为
O(log n)
的算法解决此问题吗?
package org.example.solution.day1;
import com.alibaba.fastjson.JSONObject;
public class SearchRange {
//1.target 不存在,返回[-1, -1]
public int[] searchRange(int[] nums, int target) {
if(nums.length == 0){
return new int[]{-1,-1};
}
int left = 0,right = nums.length-1;
if(nums[left] > target || nums[right] < target){
return new int[]{-1,-1};
}
//2.二分查找最左边下标
int rangeLeft = searchLeft(nums,target);
//如果不存在,直接返回
if(rangeLeft == -1){
return new int[]{-1,-1};
}
//3.找最左边下标
int rangeRight = searchRight(nums,target);
return new int[]{rangeLeft,rangeRight};
}
public int searchRight(int[] nums, int target) {
int left = 0,right = nums.length-1;
while (left<right){
//二分查找取中间值得时候,如果中间值有2个,总是取得左边的那个值,这样会导致死循环。所以这里加了1.让他取右边的那个值
int middle = (left+right+1)/2;
if(nums[middle] > target){
right = middle -1 ;
}else if(nums[middle] == target){
// [left middle]
left = middle;
}else {
//中间位置不是要搜索的对象,左边界从下一个位置开始
left = middle+1;
}
}
return right;
}
public int searchLeft(int[] nums, int target) {
int left = 0,right = nums.length-1;
while (left<right){
int middle = (left+right)/2;
if(nums[middle] > target){
right = middle -1 ;
}else if(nums[middle] == target){
// [left middle]
right = middle;
}else {
//中间位置不是要搜索的对象,左边界从下一个位置开始
left = middle+1;
}
}
//这里判断一下在返回left 因为有可能数组中没有target
if(nums[left] == target){
return left;
}
return -1;
}
public static void main(String[] args) {
SearchRange searchRange = new SearchRange();
System.out.println(JSONObject.toJSONString(searchRange.searchRange(new int[]{2,2},2)));
}
}