力扣35:搜索插入位置, 总结了二分查找的通用模板写法, 彻底解决几个易混淆问题
Posted 孤 柒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣35:搜索插入位置, 总结了二分查找的通用模板写法, 彻底解决几个易混淆问题相关的知识,希望对你有一定的参考价值。
此专栏文章是对力扣上算法题目各种方法的总结和归纳, 整理出最重要的思路和知识重点并以思维导图形式呈现, 当然也会加上我对导图的详解.
目的是为了更方便快捷的记忆和回忆算法重点(不用每次都重复看题解), 毕竟算法不是做了一遍就能完全记住的. 所以本文适合已经知道解题思路和方法, 想进一步加强理解和记忆的朋友, 并不适合第一次接触此题的朋友(可以根据题号先去力扣看看官方题解, 然后再看本文内容).
关于本专栏所有题目的目录链接, 刷算法题目的顺序/注意点/技巧, 以及思维导图源文件问题请点击此链接. 导图中源码在文章最后.
本文可以转载,但请注明来处,觉得整理的不错的小伙伴可以点赞关注支持一下哦!
博客中思维导图的高清PDF版本,可关注公众号 一起学计算机 点击 资源获取 获得
目录
0.导图整理
二分查找的几个重点如下:
1.先确定查找区间的左右开闭情况
这是写二分查找最根本的问题, 因为根据不同的情况, 下面的操作是完全不同的, 这也是很多朋友感觉二分查找难写的地方, 这里为了方便, 我直接将区间定义为左闭右开[left, right)的形式, 这里根据自己的习惯最好将区间完全固定住, 以后都按照一种模式来写, 如果你习惯左闭右闭也同样固定住, 这样不用每次都纠结.
固定为左闭右开的好处是: 很多函数中对区间的操作都是左闭右开的形式, 这算是语言的特点吧, 比如字符串中截取子串长度, 列表的截取都是左闭右开的形式, 这样就可以和语言特点相对应.
另一个好处就是在返回值的问题上, 下文会提到.
2.数组长度
当区间固定住为左闭右开, 数组长度就固定为[0, len(nums)), 这也是左右断点的初值, 如为左闭右闭, 那长度就是[0, len(nums)-1]了.
3.循环退出条件
这里也要特别注意, 代码为 while left < right 因为区间是右开, 所以不能有=, 否则区间就不存在了, 这样写循环控制的另外一个好处就是在退出循环时, 必然满足 left == right, 这样在最后的返回值就可以任意返回了, 因为它们完全相等, 而不用去纠结该返回哪个端点了.
4.中间值的写法
写法为 mid = left + (right - left)//2 , //2在Python中表示整数, /2在Python中表示正常除, 是有余数的, 这点和其他语言有所不同. 这样写的好处也非常简单, 就是为了防止大数溢出, 因为写成(left + right)//2时, 当数比较大时, left + right是有溢出的风险的, 这种写法就可以避免了.
5.中间值和目标值的比较关系
if nums[mid] < target 这个比较关系涉及到上图中4和5的两种变形, 写成什么样的形式是不固定的, 这里是根据题目要求来写的.
简单来说就是如果是<, 那么当nums[mid]达到是比target小的数中的最大的数的时候, 通过if条件进入, left的值为mid+1后的值必然是大于等于target的值, 这时候可能取到和target相等的位置.
但是当换成≤时, 当nums[mid] == target时, 仍然会进入if条件, left的值为mid+1后的值必然是大于target的值, 这时候就不可能取到和target相等的位置. 就会收敛到第一个大于target的位置.
这点还是有点复杂的, 可以好好多看几遍.
第5条是说数组由递增该为递减, 其实只要将判断条件反过来就可以了, 还是很好理解的.
6.左右区间的变化
区间的变化完全取决于区间的定义, 因为左闭, 所以左区间为left = mid+1, 因为右开, 所以右区间变换为right = mid, 其实真实取的值也就是mid-1
7.最终返回值
最后的返回值上文已经说过了, 随便返回哪个都可以
这个模板算是比较好记忆, 也比较简介的模板了, 如果你也比较习惯左闭右开的区间, 直接理解记住此模板就可以了, 如果你习惯左闭右闭的区间, 那稍微更改下也就可以了.
源码
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) #采用左闭右开区间[left,right)
while left < right: # 右开所以不能有=,区间不存在
mid = left + (right - left)//2 # 防止溢出, //表示整除
if nums[mid] < target: # 中点小于目标值,在右侧,可以得到相等位置
left = mid + 1 # 左闭,所以要+1
else:
right = mid # 右开,真正右端点为mid-1
return left # 此算法结束时保证left = right,返回谁都一样
感觉作者写的不错的, 别忘了点赞关注加收藏哦(一键三连)!你的支持会带给我极大的动力, 写出更多优秀文章!
我的更多精彩文章链接, 欢迎查看
各种电脑/软件/生活/音乐/动漫/电影技巧汇总(你肯定能够找到你需要的使用技巧)
经典动漫全集目录 精彩剧集
火影忍者 动漫 全集目录 分章节 精彩打斗剧集 思维导图整理
计算机专业知识 思维导图整理
最值得收藏的 Python 全部知识点思维导图整理, 附带常用代码/方法/库/数据结构/常见错误/经典思想(持续更新中)
最值得收藏的 C++ 全部知识点思维导图整理(清华大学郑莉版), 东南大学软件工程初试906科目
最值得收藏的 计算机网络 全部知识点思维导图整理(王道考研), 附带经典5层结构的中英对照和框架简介
最值得收藏的 算法分析与设计 全部知识点思维导图整理(北大慕课课程)
最值得收藏的 数据结构 全部知识点思维导图整理(王道考研), 附带经典题型整理
最值得收藏的 人工智能导论 全部知识点思维导图整理(王万良慕课课程)
最值得收藏的 数值分析 全部知识点思维导图整理(东北大学慕课课程)
最值得收藏的 数字图像处理 全部知识点思维导图整理(武汉大学慕课课程)
红黑树 一张导图解决红黑树全部插入和删除问题 包含详细操作原理 情况对比
各种常见排序算法的时间/空间复杂度 是否稳定 算法选取的情况 改进 思维导图整理
人工智能课件 算法分析课件 Python课件 数值分析课件 机器学习课件 图像处理课件
考研相关科目 知识点 思维导图整理
考研经验--东南大学软件学院软件工程(这些基础课和专业课的各种坑和复习技巧你应该知道)
东南大学 软件工程 906 数据结构 C++ 历年真题 思维导图整理
最值得收藏的 考研高等数学 全部知识点思维导图整理(张宇, 汤家凤), 附带做题技巧/易错点/知识点整理
最值得收藏的 考研线性代数 全部知识点思维导图整理(张宇, 汤家凤), 附带惯用思维/做题技巧/易错点整理
考研思修 知识点 做题技巧 同类比较 重要会议 1800易错题 思维导图整理
考研近代史 知识点 做题技巧 同类比较 重要会议 1800易错题 思维导图整理
考研马原 知识点 做题技巧 同类比较 重要会议 1800易错题 思维导图整理
考研数学课程笔记 考研英语课程笔记 考研英语单词词根词缀记忆 考研政治课程笔记
Python相关技术 知识点 思维导图整理
Numpy常见用法全部OneNote笔记 全部笔记思维导图整理
Pandas常见用法全部OneNote笔记 全部笔记思维导图整理
Matplotlib常见用法全部OneNote笔记 全部笔记思维导图整理
PyTorch常见用法全部OneNote笔记 全部笔记思维导图整理
Scikit-Learn常见用法全部OneNote笔记 全部笔记思维导图整理
Java相关技术/ssm框架全部笔记
科技相关 小米手机
以上是关于力扣35:搜索插入位置, 总结了二分查找的通用模板写法, 彻底解决几个易混淆问题的主要内容,如果未能解决你的问题,请参考以下文章
数组: 总结了二分查找的通用模板写法, 彻底解决几个易混淆问题, 力扣35:搜索插入位置