数组问题
- 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
- 你可以假设数组中无重复元素。
问题分析
首先我画一个有序的数组
从图中可以看出,目标值存在4种情况
- 在数组所有元素之前
- 等于数组中某一个元素
- 插入数组中
- 在数组所有元素之后
分析完题目后,会发现这是一个很简单的查找问题,一般来说一个简单的for循环就能解决问题,下面我们来尝试一下
代码
public int searchInsert(int[] nums, int target) {
for(int i=0;i<nums.length;i++){
if(nums[i]>=target){ //数组中的元素大于或者等于目标值就记录i,也就是目标值的位置
return i;
}
}
//插入值在数组最后就返回数组的长度
return nums.length;
}
这种最直接的方法能轻松的解决问题,时间复杂度O(n),那么有没有方法降低我们的时间复杂度呢?当然有,就是大家熟悉的二分法,这里就直接给出二分法的实现过程了
//二分法
public static int searchInsert(int[] nums, int target) {
int n=nums.length;
int left=0,right=n-1; //左右边界,这里取的right=n-1,我们查找的范围就是[0,n-1]
//终止条件,左边界大于右边界
while(left<=right){
int middle=left+(right-left)/2; //中间元素
if(target>nums[middle]){ //目标值大于中间值,目标值寻找范围应该在右边,左边界等于中间指针+1
left=middle+1;
}
else if(target<nums[middle]){//目标值小于中间值,目标值寻找范围应该在左边,右边界等于中间指针-1
right=middle-1;
}
else{
return middle; //如果找到等于目标值的元素,返回
}
}
//目标值数组之前:right+1 即-1+1=0
//目标值插入数组中:right+1
//目标值在数组后:right+1 即nums.length
return right+1;
}
时间复杂度为O(logn)