35.搜索插入位置

135 阅读2分钟

1.题目

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

请必须使用时间复杂度为 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 <= 104
  • -104 <= nums[i] <= 104
  • nums 为无重复元素的升序排列数组
  • -104 <= target <= 104

2.答题

思路1(二分查找):

  • 高低位两个指针high、low,取中间值middle,
  • 若middle指向的值等于目标值,直接返回middle
  • 若middle指向的值高于目标值,高位指针置为middle-1,
  • 若middle指向的值高于目标值,低位指针置为low+1,
public int searchInsert(int[] nums, int target) {
    int low = 0;
    int high = nums.length - 1;
    while (low <= high) {
        int middle = (high + low) / 2;
        if (nums[middle] == target) {
            return middle;
        }
​
        if (nums[middle] > target) {
            high = middle - 1;
        } else {
            low = middle + 1;
        }
    }
    return low;
}

时间复杂度

可根据二分查找的时间复杂度计算,若数组长度定位n,每次二分查找,查找区间变为原来的1/2,具体变化如下:

取值区间.png

当区间的值等于1时,必定会结束循环,也就是2^k = n,k是循环次数,k=logn,所有这个方法的时间复杂度可以即为O(logn)

空间复杂度

常量O(1)

提交结果:

提交结果1.png

二分查找的局限性

既然提到了二分查找,顺便说一下二分查找的局限性:

  1. 依赖有序数组

如果数组是无需的,那无法通过区间的缩小来界定目标值的位置,想要对无需数组二分查找的话,需要先排序,如果使用复杂度O(nlogn)的排序,时间复杂度就没法保证O(logn),而且会导致原数组的顺序变化。

  1. 依赖数组

二分查找通过数组下标查找数据,如果是链表的话,就没有快速找到指定的值

  1. 数据太大不适合

由于依赖数组,数组使用的是连续空间,如果数组过大,也就是连续的内存空间会很长,比如说2G的空间,这样用数组存储都是不太合适的,也就不适合用二分查找了。

最近面试,时间少,暂时只想到一种解法,先这样,Good Lock