LeetCode每日一题:35. 搜索插入位置 (2021/12/13)

461 阅读1分钟

题目链接

35. 搜索插入位置

题目

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

注意: 请必须使用时间复杂度为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;
}