LeetCode 35. 搜索插入位置(易)
减治:通过不断排除非目标元素,在循环结束之后,最后剩下的那个元素,必然是我们想要的目标元素。减治思想特点,将二分法查找区间,从以前的[left, mid]
、mid
、[mid, right]
三个部分改成两个区间。
题目
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例
示例 1:
1 |
|
示例 2: 1
2输入: [1,3,5,6], 2
输出: 11
2输入: [1,3,5,6], 7
输出: 41
2输入: [1,3,5,6], 0
输出: 0
考察知识点
数组、二分查找
核心思想
基于普通二分查找
利用二分查找,找到了就直接返回,没找到,根据返回小标对应数组中的值和target的关系,做一些特判也可以返回确定应该插入的位置。
基于减治思想的二分查找
减治:通过不断排除非目标元素,在循环结束之后,最后剩下的那个元素,必然是我们想要的目标元素。
减治思想特点,将二分法查找区间,从以前的[left, mid]
、mid
、[mid, right]
三个部分改成两个区间。
减治思想代码步骤
区间划分代码写法
当边界收缩行为是left = mid
时,出现死循环的原因。注意 left = middle-1
,right = middle
的情况下,循环条件是 left < right
,此时是不会出现死循环的。不能写成 left = middle-1
,right = middle+1
,循环条件为 left <= right
,这样会出现死循环。
思路:(如果二分查找一开始写不出来,可以尝试先写暴力法,分析清楚细节)在有序数组中查找插入元素的位置,显然可以使用二分查找。这篇题解提供的思路是“减治思想(排除法)”,即在循环的过程中,不断排除不需要的解,最后剩下的那个元素就一定是我们想要的。
- 首先,插入位置有可能在数组的末尾(题目中的示例 3),需要单独判断;
- 其次,如果待插入元素比最后一个元素严格小,并且在这个数组中有和插入元素一样的元素,返回任意一个位置即可;
- 否则,插入的位置应该是严格大于 target 的第 1 个元素的位置。(这里是关键) 因此,严格小于
target
的元素一定不是解,根据这个思路,可以写出如下代码。
关于二分查找问题的总结
参考链接
Python版本
基于普通二分查找
1 |
|
时间复杂度,就一个二分查找 \(O(logN)\) 。
空间复杂度为,只需要存储几个变量的额外空间 \(O(1)\)。
执行用时 :32 ms, 在所有 Python3 提交中击败了98.83%的用户
内存消耗 :14 MB, 在所有 Python3 提交中击败了30.81%的用户
基于减治思想的二分查找
推荐此方法,更简洁!
1 |
|
时间复杂度,就一个二分查找 \(O(logN)\) 。
空间复杂度为,只需要存储几个变量的额外空间 \(O(1)\)。
执行用时 :40 ms, 在所有 Python3 提交中击败了95.76%的用户
内存消耗 :14 MB, 在所有 Python3 提交中击败了31.52%的用户
有效语法糖
1、利用typing模块进行参数检测
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!