二分查找针对有序的数列集合,查找思想类似于分治思想,每次都和区间的中间元素对比,将要查找的区间缩小为原来的一半,直到找到要查找的元素,或者区间缩小为0。
时间复杂度:O(logn)(堆和二叉树的操作时间复杂度也是O(logn))
def binary_search(nums, n, value):
"""递归实现在没有重复元素的数组中查找给定值,找到则返回元素下标,否则返回-1"""
return _binary_search_v2(nums, 0, n-1, value)
def _binary_search(nums, low, high, value):
"""二分查找实现函数,在指定区间查找给定元素"""
if low > high:
return -1
mid = low + ((high - low) >> 1)
if nums[mid] == value:
return mid
elif nums[mid] < value:
return _binary_search(nums, mid+1, high, value)
else:
return _binary_search(nums, low, mid - 1, value)
def binary_search_v1(nums, n, value):
"""循环实现在没有重复元素的数组中查找给定值,找到则返回元素下标,否则返回-1
:param nums: 待查找的列表
:param n: 列表元素个数
:param value: 要查找的元素
:return:
"""
low, high = 0, n-1
while low <= high:
# mid = int((high+low)//2) # high+low可能溢出,将除法运算转换为移位运算
mid = low + ((high - low) >> 1)
if nums[mid] == value:
return mid
elif nums[mid] < value:
low = mid + 1
else:
high = mid - 1
return -1
def sqrt(num, n=6):
"""求一个数的平方根,精确到小数点后n位
先确定整数部分,再确定小数部分,小数部分每次确定一位,最后四舍五入
:param num:
:param n:
:return:
"""
# 保留小数点后n+1位
for i in range(0, n+2):
if i == 0:
low, high = 0, num
else:
low, high = round(res+0.0/(10**i),i), round(res+10.0/(10**i),i)
res= round(_sqrt(num, low, high, i),i)
# 对最后一位四舍五入
return round(res, n)
def _sqrt(num, low, high, i):
"""对[low, high]范围内的i位数二分查找确定num的平方根
:param num: 目标数
:param low: 二分查找下界
:param high: 二分查找上界
:param i: 查找位数,为0时表示整数部分
:return:
"""
while low <= high:
if i == 0:
mid = low + ((high - low) >> 1)
else:
mid = round(low + ((high - low)/2), i)
if mid ** 2 == num:
return mid
elif mid**2 < num and (mid+1/(10**i))**2 > num:
return mid
elif mid**2 < num:
low = round(mid+1/(10**i),i)
elif mid**2 >num and (mid-1/(10**i))**2 < num:
return mid-1/(10**i)
else:
high = round(mid-1/(10**i),i)
def binary_search(nums, n, value):
"""
在包含重复元素的数组中查找第一个值等于给定值的元素,没有则返回-1
:param nums:
:param value:
:return:
"""
low, high = 0, n-1
while low < high:
mid = low + ((high - low) >> 1)
if nums[mid] >= value:
high = mid
else:
low = mid + 1
if nums[low] == value:
return low
else:
return -1
def binary_search(nums, n, value):
"""
在包含重复元素的数组中查找最后一个值等于给定值的元素,没有则返回-1
:param nums:
:param value:
:return:
"""
low, high = 0, n-1
while low < high:
mid = low + ((high - low + 1) >> 1) # 此处加1是为了当low和high相邻时mid取到high
if nums[mid] <= value:
low = mid
else:
high = mid - 1
if nums[low] == value:
return low
else:
return -1
def binary_search(nums, n, value):
"""
在包含重复元素的数组中查找第一个值大于等于给定值的元素
:param nums:
:param value:
:return:
"""
low, high = 0, n-1
while low < high:
mid = low + ((high - low) >> 1)
if nums[mid] >= value:
high = mid
else:
low = mid + 1
return low
def binary_search(nums, n, value):
"""
在包含重复元素的数组中查找最后一个值小于等于给定值的元素
:param nums:
:param value:
:return:
"""
low, high = 0, n-1
while low < high:
mid = low + ((high - low + 1) >> 1) # 此处加1是为了当low和high相邻时mid取到high
if nums[mid] <= value:
low = mid
else:
high = mid - 1
return low