「前端刷题」35. 搜索插入位置

45 阅读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

解题思路

  • 这个题目本质上是利用二分法查找左边界

代码

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var searchInsert = function (nums, target) {
  if (nums == null || !nums.length) {
    return -1;
  }
  // 左闭右闭区间
  let begin = 0,
    end = nums.length-1;
  while (begin <= end) {
    // 下面这样写是考虑大数情况下避免溢出
    let mid = begin + ((end - begin) >> 1);
    if (nums[mid] > target) {
      // 在左半区间中查找
      end = mid - 1;
    } else if (nums[mid] < target) {
      // 在右半区间中查找
      begin = mid + 1;
    } else {
      // 正好就是
      return mid;
    }
  }
  // 查找的是左边界,所以返回begin
  return begin;
};

思路2

拿到此题,首先看到题目要求二分查找,在原来的二分查找思路上外加一个返回插入的值,至于为什么是return left,是因为当left+1结束时,right执行完此语句也不会对程序产生什么影响

代码

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var searchInsert = function(nums, target) {
    let left = 0,right = nums.length - 1; 
    while (left <= right) {
        const mid = Math.floor((right - left)/2) + left;
        const mids = nums[mid];
        if (mids < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return left;
};

最后

曾梦想仗剑走天涯

看一看世界的繁华

年少的心总有些轻狂

终究不过是个普通人

无怨无悔我走我路