前言
力扣第三十五题 搜索插入位置 如下所示:
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
示例 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] <= 104nums为无重复元素的升序排列数组-104 <= target <= 104
一、思路
这一题看完的话,有以下两个重要的信息:
- 无重复元素的升序排列数组
- 找到目标值的位置或顺序插入的位置
我们可以将目标值是否在数组中存在分为以下两种情况:
- 目标值存在:使用二分法可以很轻松的找到目标值的位置
- 目标值不存在:找到第一个大于目标值的下标
如果目标值不存在,为什么是第一个大于目标值的下标呢?
假设
nums = [1,3,5,6], target = 4,插入的位置为2,因为有nums[2]为5是第一个大于target = 4的位置。
从论证的角度来说,假设插入的位置为 p,则一定有:nums[p-1] < target ≤ nums[p]。所以只需要找到第一个大于或等于target的位置即可。
举个例子
此处以 nums = [1,3,5,6], target = 4 作为例子
p = nums.length:目标值的位置,可能存在数组中的所有值都小于目标值
left = 0:二分法左边界
right = nums.lengt - 1:二分法右边界
mid = (left + right)/2 = 1,此时nums[mid] < target,说明在右半边。left = mid + 1 = 2mid = (left + right)/2 = 2,此时nums[mid] > target,赋值p = mid = 2,right = mid - 1 = 1- 此时
left > right,结束循环。返回结果2
二、实现
实现代码
实现代码与思路中保持一致
/**
* 二分法
* 不断找到第一个大于等于target的值
*/
public int searchInsert(int[] nums, int target) {
int len = nums.length;
int ret = len;
int left = 0;
int right = len -1;
while (left <= right) {
int mid = (left + right)/2;
if (nums[mid] >= target) {
ret = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ret;
}
测试代码
public static void main(String[] args) {
int[] nums = {1, 3, 5, 6};
int target = 4;
new Number35().searchInsert(nums, target);
}
结果
三、总结
这一题最坑的就是把 无重复元素的升序排列数组 这么重要的信息写到了提示中,我第一次写的时候还判断了升序和降序两种情况。说明平时刷题一定要仔细看题啊!tnt
感谢看到最后,非常荣幸能够帮助到你~♥