持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情
1、前言
每天一个算法小练习,本篇使用Java实现。
2、题目描述
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1, -1]。你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
- 0 <= nums.length <= 105
- -109 <= nums[i] <= 109
- nums 是一个非递减数组
- -109 <= target <= 109
2.1、示例1
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
2.2、示例2
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
2.3、示例3
输入:nums = [], target = 0
输出:[-1,-1]
3、解题思路
3.1、二分查找
给的数组是有序的,最直接的我们可以从头到尾遍历一次,就能找到开始和结束的位置。但这样时间复杂度为,就不符合题目要求了。我们可以使用二分查找,二分查找的时间复杂度为。可以先找左边界,即首个等于 target 值的数,且它的前一个值部位 target,右边界即等于 target 值,同时后一个数不等于target。
class Solution {
public int[] searchRange(int[] nums, int target) {
int left = 0;
int right = nums.length-1;
//中间位置
int mid = (left + right) >> 1;
int num[] = new int[2];
num [0] = -1;
num [1] = -1;
int i =0;
while (left <= right) {
if((i == 0 && nums[mid] == target && ( mid == 0 || nums[mid-1] != target))||(i == 1 && nums[mid] == target && (mid == end || nums[mid+1] != target ))) {
num[i++] = mid;
mid = (start + end)>>1;
} else if(nums[mid] > target){
end = mid-1;
}else if(nums[mid] < target){
start = mid+1;
}else if(i == 0){
//找左边界
mid = mid -1;
}else if(i == 1){
//找右边界
mid = mid + 1;
}
if(nums[mid] != target){
mid = (start+end)>>1;
}
if(i == 2) {
break;
}
}
return nums;
}
}
执行结果:
-
时间复杂度:,n为数组的长度,因为二分查找的时间复杂度为。
-
空间复杂度:
好了、本期就先介绍到这里,有什么需要交流的,大家可以随时私信我。😊