参考相关文章:https://www.zhihu.com/question/36132386
直接举例子:
数组:a = [1,2,2,3,3,4,4]
问题:
1. 找到第一个(大于)等于`3`的位置;(答案:`3`)
2. 找到第一个大于`3`的位置;(答案:`5`)
3. 找到最后一个小于(等于)`3`的位置;(答案:`4`)
4. 找到最后一个小于`3`的位置.(答案:`2`)
我们知道用二分法可以解决,也没有一种方法就可以把上面问题都可以解决的!
答案是:有的
我们只要记住第一个问题,后面的问题要不是相似,要不是互补的!也可以不记住,可以参考上面的文章链接,自己理解!
首先前面两个问题都是求下界.后面两个问题求上界.
问题1
就是说,找到第一个(大于)等于3
的位置,即找满足x >= value
或者x >value
条件的最小x的位置.
代码如下:
def lower_bound(array, first, last, value):
while first < last:
mid = first + (last - first) // 2
if array[mid] < value:
first = mid + 1
else:
last = mid
return first
代码解释:
first:
是列表的开始位置,last:
是列表的结束位置,value:
是搜索的值
Note:
- 取中位数,使用
first + (last - first) // 2
,详细说明请看上面链接 if
的判断条件为<
- 满足条件:
first
要+1
,else
语句则不需要 - 返回
first
和last
一样,两个值相等
测试代码:
a = [1, 2, 2, 3, 3, 4, 4]
print(lower_bound(a, 0, 7, 3))
显示结果:
3
问题2
就是说,找到第一个大于3
的位置,即第一个大于value
的位置.
代码如下:
def lower_bound(array, first, last, value):
while first < last:
mid = first + (last - first) // 2
if array[mid] <= value:
first = mid + 1
else:
last = mid
return first
代码解释:
聪明的小伙伴,已经发行不同了,就是if
的判断条件变成<=
了
测试代码:
print(lower_bound(a, 0, 7, 3))
显示结果:
5
问题3
问题3和问题2是互补的,只要把问题2,得出结果-1
,就是这道题答案.
问题4
问题4和问题1是互补的,只要把问题1,得出结果-1
.
自己体会吧!
掌握这个万能的二分搜索,妈妈再也不用担心我的学习啦!
嘻嘻!