力扣第三十五题-搜索插入位置 | 8月更文挑战

252 阅读2分钟

前言

力扣第三十五题 搜索插入位置 如下所示:

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

示例 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

一、思路

这一题看完的话,有以下两个重要的信息:

  • 无重复元素的升序排列数组
  • 找到目标值的位置或顺序插入的位置

我们可以将目标值是否在数组中存在分为以下两种情况:

  • 目标值存在:使用二分法可以很轻松的找到目标值的位置
  • 目标值不存在找到第一个大于目标值的下标

如果目标值不存在,为什么是第一个大于目标值的下标呢?

假设 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:二分法右边界

  1. mid = (left + right)/2 = 1,此时 nums[mid] < target,说明在右半边。left = mid + 1 = 2
  2. mid = (left + right)/2 = 2,此时 nums[mid] > target,赋值 p = mid = 2right = mid - 1 = 1
  3. 此时 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);
    }

结果

image.png

三、总结

这一题最坑的就是把 无重复元素的升序排列数组 这么重要的信息写到了提示中,我第一次写的时候还判断了升序和降序两种情况。说明平时刷题一定要仔细看题啊!tnt

感谢看到最后,非常荣幸能够帮助到你~♥