问题描述
在排序数组中查找元素的第一个和最后一个位置
给定一个按照升序排列的整数数组 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]
解决方案
第一种,这种方法不管空间复杂度的话,是一种很好想的方法,遍历数组,找到目标后,判断是否是第一次出现,不是就放到后面的位置去。但题目要求空间复杂度为O(log n) ,这种方法循环过多,明显是不对的。
第二种,我们可以注意到题目说了是升序数组,随意不难想到升序数组。
代码
int[] nums = {
5,7,7,8,8,10};
int[] a = {
-1,-1};
int target = 8;
//方法1
for (int i=0;i<nums.length;i++){
if(nums[i]==target){
if (a[0]==-1){
a[0] = i;
}else{
a[1] = i;
}
}
}
for (Integer i:a) {
System.out.println(i);
}
//方法2
int left = 0;
int right = nums.length-1;
while(left<=right){
int mid = (left + right)/2;
if(nums[mid]==target){
while(mid>=left && nums[mid]==target){
mid--;
}
a[0] = mid+1;
mid = (left + right)/2;
while(mid<=right && nums[mid]==target){
mid++;
}
a[1] = mid - 1;
break;
}else if (nums[mid] > target){
right = mid-1;
}else{
left = mid+1;
}
}
for (Integer i:a) {
System.out.println(i);
}
总结
通过方法一和方法二的对比不难发现,用二分法的代码是真的长,但方法二满足了题目中对空间复杂度的要求。