力扣题解:搜索插入位置

62 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情

题目描述

原题链接 :

35. 搜索插入位置 - 力扣(LeetCode)

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

请必须使用时间复杂度为 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

 

提示:

  • 1 <= nums.length <= 10^4
  • -10^4 <= nums[i] <= 10^4
  • nums 为 无重复元素 的 升序 排列数组
  • -10^4 <= target <= 10^4

思路分析

三部曲不多说;

这道题可以采用普通的双指针对撞,但是复杂度稍微高点。可以用二分查找。

首位双指针,求他们的mid位置,比较mid位置的值,然后移动首位指针之一到mid上。

需要注意的是循环结束的条件,p1<p2-1;以免陷入p1一直等于mid的循环中;

最后判断p1、p2位置和目标值的大小关系,以确定目标值的位置。

AC 代码

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var searchInsert = function(nums, target) {
    if(!nums){
        return 0
    }
    var len = nums.length;
    var p1 = 0;
    var p2 = len -1;
    while(p1<p2-1){
        var mid = Math.floor(p1+(p2-p1)/2)
        if(nums[mid]===target){
            return mid
        }else if(nums[mid]>target){
            p2=mid
        }else{
            p1=mid
        }
    }
    if(nums[p1]>=target){
        return p1
    }else if(nums[p2]<target){
        return p2+1
    }else{
        return p2
    }
};

总结

注意容易出错的 3 个地方。

循环退出条件是 low <= high,而不是 low < high;
mid 的取值,可以是 mid = (low + high) / 2,但是如果 low 和 high 比较大的话,low + high 可能会溢出,所以这里写为 mid = low + ((high - low) >> 1);
low 和 high 的更新分别为 low = mid + 1、high = mid - 1。

参考

标准二分查找法题目,直接套模板 - 搜索插入位置 - 力扣(LeetCode)

35.左边界二分法模板题 - 搜索插入位置 - 力扣(LeetCode)