二分查找与补丁规避

● 每周一言

越努力,越幸运。

导语

二分查找(binary search)可以说是最常见的算法思想之一了。即便是如此直观简单的算法,在不同场景下的实现方式也存在着微妙差别,稍有马虎就需要打上冗余难看的补丁来防止各种badcase。

趁着周末,小斗带着对binary search的浓厚兴趣,在这里作一下思考总结,并讲讲对补丁规避的理解。

binary search

二分查找的前提条件是待查找数据必须具备一定的有序关系,这个有序可以是升序、降序,或者某种扩展的顺序关系。从二分查找算法执行的方式来看,不出以下三种情形:

fig1

情形a,二分不带mid中间值。这种情形作为二分查找最简单的形式,一般只要求查找某一特定值的位置,且待查找序列中的元素不出现重复。比如在 [1, 3, 4, 6, 7, 9] 中查找4则返回下标2,查找5则返回-1。

情形b,二分左带mid中间值。这种情形适用于查找相同元素的左边界。比如在 [1, 3, 4, 4, 4, 5, 7, 9] 中查找4,返回的下标为2。

情形c与情形b相反,为二分右带mid中间值。针对上述例子 [1, 3, 4, 4, 4, 5, 7, 9],同样查找4,返回的下标则为4。

fig2

在具体二分问题当中,有时并不想要精确匹配,而是想找最相近或是k个最相近的值。这时,在二分查找结束后就需要作进一步的算法处理。

此外,还存在不少二分查找的问题变种,其实都是万变不离其宗,只要找准了两个关键点便能迎刃而解。这两个关键点分别为:1. 确定有序序列是什么;2. 确定mid比较方式。

所谓补丁,就是解决一些特殊情况或是边界问题的代码。比如,当待查找数据为空数据时,是不需要执行算法的,如果不加处理,往往会报下标溢出之类的错误。

fig3

除开上述必要补丁,如果希望规避其他冗余补丁,首先,需要考虑的是算法是否涵盖除特殊情况以外的所有case;其次,算法如果已涵盖所有case,是否能等同对待其中的边界case。若不能做到上述两点,冗余补丁就不可避免了,代码自然就会比较丑陋而不优雅。

比如,在上述二分算法中,如果处理的最小序列长度为3,那么长度为0、1和2的序列就分别需要打补丁,这样是不合理的。

以上便是二分查找与补丁规避,敬请期待下节内容。

结语

感谢各位的耐心阅读,后续文章于每周日奉上,敬请期待。欢迎大家关注小斗公众号 对半独白

face

发布了91 篇原创文章 · 获赞 113 · 访问量 27万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章