LeetCode搜索插入位置(Python)——二分查找

题目

LeetCode搜索插入位置(Python)——二分查找_第1张图片

解题思路

除开暴力解法一个一个比,自然会想到二分查找,但众所周知写对一个二分查找并不是一件简单的事,首先第一点要注意边界判断,第二点要注意在每一次循环中,[left, right]区间都要有所改变,不然会陷入死循环,我的代码如下:
LeetCode搜索插入位置(Python)——二分查找_第2张图片

第一个if-elif-else即为边界判断,不多说了;想说明的一点是,while的条件可能不太容易明白,我的循环终止条件为 right - left = 1,因为如果target在数组中,那么肯定会找到一个区间[ left, right ]使得 nums[( left+right ) // 2] = target,也就是经由if分支return,如果target不在数组中,最后一定是找到一个[ left, right ]区间,满足 nums[ left ] < target < nums[ right ],且 right - left = 1,这时return right 即可。

比如 right - left = 2 时,闭区间 [ left, right ] 会包含三个数字,仍可以再判断一次中值,收敛区间,但当 right - left = 1 时,( right + left ) // 2 = ( 2*left + 1 ) // 2 会恒等于 left,这时 target > nums[ left ],接下来就是 left = ( right + left ) // 2 = left,这就不满足之前说的每一次循环区间都要有所改变的准则,所以选择在这时跳出循环。

执行结果为:
LeetCode搜索插入位置(Python)——二分查找_第3张图片
接下来看了一下评论区大神们的代码,发现自己还是渣渣,几行代码就能解决的事情,我写了这么多?二分查找的通用模板大致如下:
LeetCode搜索插入位置(Python)——二分查找_第4张图片
我们来分析一下,首先对于第二点,每一次循环区间都要发生变化,可以看到处理的不同之处在于left = mid + 1,如果target不在数组中,最后还是会找到刚才说的那样一个区间,当right - left = 1 时,mid 等于 left ,这时left还是强制往右移动了一位,然后left = right 跳出循环,没问题。

对于第一点边界的判断,如果目标值比数组最小值还小,right一直=mid,最后mid=left,那么跳出循环时 left = right = 0,如果目标值比数组最大值还大,那么跳出循环时 left = right = len( nums ) 也没有问题!需要注意的细节就是,首先right一开始赋初值时赋的是len(nums)而不是 len(nums)-1,这就使得如果目标值比数组最大值还大时,left能一直往右移动直到left = right.

你可能感兴趣的:(LeetCode之路)