[路飞]_一起刷leetcode 35. 搜索插入位置

「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战

题目

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 <= 104
  • -104 <= nums[i] <= 104
  • nums 为无重复元素升序排列数组
  • -104 <= target <= 104

暴力解法

思路

  1. 已经排序好的数组,我们拿到后找到元素插入的位置,这题目一听就是一个插入排序;
  2. 直接从第一个元素开始跑一遍循环,如果比元素小则继续遍历,直到比元素大就返回;
  3. 如果全部找完没找到比元素大的,那就在数组最后面插入。

实现

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var searchInsert = function(nums, target) {
    for (let i = 0; i < nums.length; i++) {
        if(nums[i] >= target) {
            return i;
        }
    }
    
    return nums.length;
};
复制代码

二分查找

思路

  1. 上面暴力解法平均复杂度是O(logn),但是如果遇到每次都是插入个最大值,就达到了O(n);显然不符合我们题目的要求,于是我们需要进行优化;
  2. 我们可以每次从中点开始找,如果比元素小就从前面的半截数据中继续找,否则就从后面的半截数据中找,这样子我们只需要做 O(log2 n)次查找就能找到答案。

实现

/**
 * @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((left + right) / 2);
        if (nums[mid] === target) {
            return mid;
        } else if (nums[mid] < target) {
           left = mid + 1; 
        } else {
            right = mid - 1;
        }
    }
    return left;
};
复制代码

注意点

二分查找注意每次赋值的时候,如果是给左节点赋值要用mid + 1, 给右节点赋值要用mid - 1; 不然会陷入无限循环中去。

看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。

猜你喜欢

转载自juejin.im/post/7032542266136723493
今日推荐