一、题目描述
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
示例 1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1
示例 3:
输入: nums = [1,3,5,6], target = 7
输出: 4
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 为 无重复元素 的 升序 排列数组
-104 <= target <= 104
二、题目解析
核心思路:因为时间复杂度要求,所以不可用for循环直接遍历,改为二分查找的思路。
注意边界条件容易出错。
当不存在target元素,总能到达一种状态,left=right=mid,此时,如果mid元素小于target,left=mid+1,越界,此时left位置为target应插入位置;
如果mid元素大于target,right=mid-1,越界,此时left位置为target应插入位置;
当原数组不包含target时,考虑while循环最后一次执行的总是 left=right=mid,
* 此时nums[mid] 左边的数全部小于target,nums[mid]右边的数全部大于target,
* 则此时我们要返回的插入位置分为两种情况:
* ①就是这个位置,即nums[mid]>target时,此时执行了right=mid-1,返回left正确
* ②是该位置的右边一个,即nums[mid]<target时,此时执行了left=mid+1,返回left也正确
1、递归
class Solution {
public int searchInsert(int[] nums, int target) {
int left = 0,right = nums.length - 1;
return searchInsertRecursive(nums,left,right,target);
}
public int searchInsertRecursive(int[] nums,int left,int right,int target) {
int mid = (right + left) / 2;
if(left > right){
return left;
}
if(nums[mid] == target){
return mid;
}else if(nums[mid] > target){
return searchInsertRecursive(nums,left,mid - 1,target);
}else if(nums[mid] < target){
return searchInsertRecursive(nums,mid + 1,right,target);
}
return -1;
}
}
2、循环
class Solution {
public int searchInsert(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while(left <= right) {
int mid = (left + right) / 2;
if(nums[mid] == target) {
return mid;
} else if(nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left;
}
}
2588

被折叠的 条评论
为什么被折叠?



