题目链接
题目
给定一个排序数组和一个目标值,在数组中找到目标值
并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
注意:
请必须使用时间复杂度为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
复制代码
- 示例 4
//输入: nums = [1,3,5,6], target = 0
//输出: 0
复制代码
- 示例 5
//输入: nums = [1], target = 0
//输出: 0
复制代码
- 提示:
1 <= nums.length <= 10⁴
-10⁴ <= nums[i] <= 10⁴
nums 为无重复元素的升序排列数组
-10⁴ <= target <= 10⁴
复制代码
方法解答
暴力破解
一般来讲,关于数组方面的题目一般都会有暴力破解的方法,基本上流程如下
- 判断数组的边界条件
- for循环遍历,target依次跟数据元素比较,输出值
- 针对特殊情况,进行单独判断输出
代码如下
public static int searchInsert(int[] nums, int target) {
//判断nums的边界情况
if (nums == null || nums.length == 0) {
return -1;
}
int n = nums.length;
for (int i = 0; i < n ; i++) {
//如果数组的值大于等于target,直接返回,该数组的index
if (nums[i] >= target) {
return i;
}
}
//遍历完成后,target大于数组最后一位的值,直接返回数组的长度。
return n;
}
复制代码
虽然暴力破解方法基本适用于所有的数组问题,但是根据题目要求时间复杂度必须要O(log n)
,很明显暴力破解的时间复杂度是O(n),可以知道主要考察的二分查找方法的使用。
二分查找
二分查找基本上就有一套模版,流程如下
- 设置左侧下标left,右侧下标rught
- 通过while循环,计算中间下表mid
- 根据nums[mid] 和 target 之间的大小进行判断,相等则直接返回下标
- nums[mid] < target 则 left 右移
- nums[mid] > target 则 right 左移
- 查找结束如果没有相等值则返回 left,该值为插入位置
代码如下
public static int searchInsert(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return -1;
}
int l = 0;
int r = nums.length - 1;
while (l <= r) {
int mid = (l + r) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] > target) {
r = mid - 1;
} else {
l = mid + 1;
}
}
return l;
}
复制代码
近期评论