版权声明:本文为博主原创文章,如有转载请标注来源。 https://blog.csdn.net/shengchaohua163/article/details/79789096
二分搜索是算法搜索一部分的重要内容。虽然变化多端,但仍有迹可循,有法可依。记录一下在网上遇到的模板~
这个模版的核心是将二分搜索(binary search)问题转化成:在给定升序数组中,寻找第一个或者最后一个 target 元素出现的索引。有几点需要注意:
- 初始化:start = 0,end = array.length - 1
- 循环判断条件:start + 1 < end。 表示当指针指到两个元素相邻或者相交的时候, 循环停止。
- 求中间值:mid = start + (end - start) / 2,防止溢出。(Python不用考虑,但Python的除号是 //)
- 对 array[mid] 判断大小分三种情况(>, <, ==)讨论。不相等时(> 或 <),需要移动start和end,直接写 start=mid 或 end=mid,不要 +1 或者 -1 。因为只移动边界到mid的位置,不会误删除target。相等(==)时,不要写return,在程序最后的时候统一写return,这样可以增强可读性。
- 在循环结束后,因为只有1~2个元素需要讨论,所以结果非常容易解释清楚。
该模板的Python代码如下:
class Solution:
def binary_search(self, array, target):
if not array:
return -1
start, end = 0, len(array) - 1
while start + 1 < end:
mid = (start + end) // 2
if array[mid] == target:
start = mid # 寻找最后一个target的index
# end = mid # 寻找第一个target的index
elif array[mid] < target:
start = mid
else:
end = mid
if array[start] == target:
return start
if array[end] == target:
return end
return -1
题目:lintcode No.61. Search for a Range
根据上面的模板进行解题。核心步骤为:1.寻找第一个 target 元素的index 2.寻找最后一个 target 元素的 index。 Python代码如下:
class Solution:
"""
@param A: an integer sorted array
@param target: an integer to be inserted
@return: a list of length 2, [index1, index2]
"""
def searchRange(self, A, target):
# write your code here
res = [-1, -1]
if not A:
return res
# search the first target index of target
start, end = 0, len(A) - 1
while start + 1 < end:
mid = (start + end) // 2
if A[mid] == target:
end = mid # 寻找第一个target的index
elif A[mid] < target:
start = mid
else:
end = mid
if A[start] == target:
res[0] = start
elif A[end] == target:
res[0] = end
# search the last target index of target
start, end = 0, len(A) - 1
while start + 1 < end:
mid = (start + end) // 2
if A[mid] == target:
start = mid # 寻找最后一个target的index
elif A[mid] < target:
start = mid
else:
end = mid
if A[end] == target:
res[1] = end
elif A[start] == target:
res[1] = start
return res
参考资料: