leetCode-035 - 搜索插入位置(search-insert-position)

035 - 搜索插入位置(search-insert-position)

/*
 * @Author: lvjingshuai 
 * @Date: 2019-07-21 06:21:12 
 * @Last Modified by: lvjingshuai
 * @Last Modified time: 2019-08-16
 */
文章结构
1、题目介绍
2、解题
2.1 解法 - for()循环
2.2 解法 - 二分查找法
3、每日一问

1、题目介绍

  • 难度:简单 (系统学习算法与数据结构)
  • 涉及知识:数组、二分查找
  • 题目编号:035
  • 题目地址:https://leetcode-cn.com/problems/search-insert-position/
  • 题目内容:
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

你可以假设数组中无重复元素。

示例 1:
输入: [1,3,5,6], 5
输出: 2

示例 2:
输入: [1,3,5,6], 2
输出: 1

示例 3:
输入: [1,3,5,6], 7
输出: 4

示例 4:
输入: [1,3,5,6], 0
输出: 0

2、解题

  • 官方题解:https://leetcode-cn.com/problems/search-insert-position/solution/te-bie-hao-yong-de-er-fen-cha-fa-fa-mo-ban-python-/

上面是官方使用 Java 进行的题解。

2.1 for()循环

解题思路:

这道题通过for遍历的话,情况判断

  1. 存在,即返回下标
  2. 不存在,且遍历的每一个item的值都小于目标值 即nums[i] < target, 插入数组的末尾
  3. 不存在,且遍历的每一个item的值都大于目标值 即nums[i] > target, 插入数组的头部
  4. 不存在,且遍历的item的值存在大于和小于target 即nums[i]中有满足target插入的位置,返回插入位置的下标
  5. 其实最终的规律大家也都看出来了,即目标值大于等于item的值时,即为所求下标

解题代码:

var searchInsert = function(nums, target) {
  for (let i = 0; i < nums.length; i++) {
    if (nums[i] >= target) {
      return i;
    }
  }
  return nums.length;
};

执行测试:

  1. nums[1, 3, 5, 6]
  2. target2
  3. return1
2.2 解法 - 二分法

解题思路:

  1. 我们需要了解的是,一个数 / 2,大概率返回的是小数,而我们的索引需要的是整数,所以我们通过 Math.round() 来四舍五入获取整数。

  2. 就是 while 的逻辑判断:

  3. nums[1, 3, 5, 6]

  4. target2

  5. 我们需要知道的是,如果 target2,那么返回的 [left, right] 是:[1, 0];如果 target4,那么返回的 [left, right][2, 1]。因为循环结束的条件是 left > right,所以无疑 left 是更接近中间值的。

解题代码:

var searchInsert = function(nums, target) {
  let left = 0;
  let right = nums.length - 1;
  
  while (left <= right) {
    let middle = Math.round((left + right) / 2);
      // 等于的情况最简单,我们应该放在第 1 个分支进行判断
    if (target === nums[middle]) {
      return middle;
    } else if (target < nums[middle]) {
      right = middle - 1;
        // middle 也一定不是所求的右边界
        // 此时右边界更新为 middle - 1
    } else if (target > nums[middle]) {
         // 题目要我们返回大于或者等于目标值的第 1 个数的索引
         // 此时 middle 一定不是所求的左边界,
         // 此时左边界更新为 middle + 1
      left = middle + 1;
    }
  } 
    // 注意:一定得返回左边界 left,
    // 如果返回右边界 right 提交代码不会通过
    // 【注意】下面我尝试说明一下理由,如果你不太理解下面我说的,那是我表达的问题
    // 但我建议你不要纠结这个问题,因为我将要介绍的二分查找法模板,可以避免对返回 left 和 right 的讨论

    // 理由是对于 [1,3,5,6],target = 2,返回大于等于 target 的第 1 个数的索引,此时应该返回 1
    // 在上面的 while (left <= right) 退出循环以后,right < left,right = 0 ,left = 1
    // 根据题意应该返回 left,
    // 如果题目要求你返回小于等于 target 的所有数里最大的那个索引值,应该返回 right
  return left;
};

执行测试:

  1. nums[1, 3, 5, 6]
  2. target2
  3. return1

知识点:

  1. “神奇的” 二分查找法模板的基本思想:“排除法”
    即:在每一轮循环中排除一半以上的元素,于是在对数级别的时间复杂度内,就可以把区间“夹逼”只剩下 1 个数,而这个数是不是我们要找的数,单独做一次判断就可以了。

  2. “夹逼法”或者“排除法”二分查找算法的基本思想,“二分”是手段,在目标元素不确定的情况下,“二分” 也是“最大熵原理”告诉我们的选择。

  3. 这道题在二分上要注意思考边界,如果边界不包括目标数值,会导致错误结果

  4. 先写二分逻辑上容易想到的分支逻辑,这个分支逻辑通常是排除中位数的逻辑;

3、每日一题

webpack 的 常见的loader,常见的plugin?

webpack的定义:

  1. webpack是一个js打包工具,在webpack里一切文件皆模块,通过loader转换文件,通过plugin注入钩子,最后输出由多个模块组合成的文件。
  2. webpack功能是分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(ScssTypeScript等),并将其打包为合适的格式以供浏览器使用。

常见的loader:

  1. file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件
  2. url-loader:和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
  3. source-map-loader:加载额外的 Source Map 文件,以方便断点调试
  4. image-loader:加载并且压缩图片文件
  5. babel-loader:把 ES6 转换成 ES5
  6. css-loader:加载 CSS,支持模块化、压缩、文件导入等特性
  7. style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。
  8. eslint-loader:通过 ESLint 检查 JavaScript 代码

几个常见的plugin:

  1. define-plugin:定义环境变量
  2. terser-webpack-plugin:通过TerserPlugin压缩ES6代码
  3. html-webpack-pluginhtml文件中引入的外部资源,可以生成创建html入口文件
  4. mini-css-extract-plugin:分离css文件
  5. clean-webpack-plugin:删除打包文件
  6. happypack:实现多线程加速编译
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值