1.生活中的二分问题
猜字游戏:主持人随机写下一个0到99之间的数字,玩家来猜,每猜一次,主持人会告诉玩家他猜的数比写下的数大还是小,直到猜对。
2.时间复杂度分析
有序数组大小为n,每次查找后数据范围缩小为原来一半。最坏的情况下,区间缩小为1才结束;
区间变化为n,n/2,n/4,……,,当时,k就是查找次数;
每次查找只涉及大小比较操作,k次查找,时间复杂度为O(k);
时,,所以二分查找的时间复杂度为。
3.二分查找代码
3.1 非递归实现
def binary_search(nums, target):
i = 0
j = len(nums) - 1
m = -1
# 退出条件: <= 不是 <
while i <= j:
# m = (i + j) // 2
# 向下取整,i、j过大,i+j可能超过整形数据类型可以表示的范围
# m = i + (j-i)//2
# 除法改成位运算效率更高,右移1位相当于除以2
# 原数 0000 1000 ----8
# 右移一位 0000 0100 ----4 相当于除以2
# 再右移一位 0000 0010 ----2
m = int(i + ((j-i)>>1))
if target == nums[m]:
return m
elif target > nums[m]:
i = m + 1
else:
j = m - 1
3.2 递归实现
def binary_search_recursive(nums, target, start, end):
# nums:待查找区间
# target:目标数字
# start:0
# end:len(nums)-1
while start <= end:
m = int(start + ((end-start)>>1))
if target == nums[m]:
return m
elif target > nums[m]:
return binary_search_recursive(nums, target, m + 1, end)
else:
return binary_search_recursive(nums, target, start, m - 1)