1,二分法基本知识
二分法:是指将一个有序的数列中查找某个东西的位置或最大值、最小值、极值等一种比较快速的方法。做法是先找出数列中的中间值(mid,注:mid是指middle),判断是否符合条件,如果符合,就按照题目意思将范围增大或减小(l,r是起点和终点,范围增大是l=mid+1;(或不加1,根据题目意思来),范围减小是r=mid-1;(或不减1,根据题目意思来))。然后就会得到一段新的数列(因为l,r的值变了),重复以上步骤,直到l>r为止。
举个例子:1~100这些数,找1这个数,第一次1 ~100,中间值是50,1比50小。第二次1 ~50,中间值是25,1比25小。第三次1 ~25,中间值是13,1比13小。第四次1 ~13,中间值是7,1比7小。第五次1 ~7,中间值是4,1比4小。第六次1 ~4,中间值是2,1比2小。第七次1 ~2,中间值是1,1与1相同。一共七次就行了,非常快。
2,例一(leetcode:69. x 的平方根 )
2.1,题目描述
给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。
示例 1:
输入:x = 4
输出:2
示例 2:
输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842…, 由于返回类型是整数,小数部分将被舍去。
2.2,题目解释
由于 x 平方根的整数部分 ans 是满足 k^2 ≤x 的最大 k 值,因此我们可以对 k 进行二分查找,从而得到答案。
二分查找的下界为 0,上界可以粗略地设定为 x。在二分查找的每一步中,我们只需要比较中间元素 mid 的平方与 x 的大小关系,并通过比较的结果调整上下界的范围。由于我们所有的运算都是整数运算,不会存在误差,因此在得到最终的答案 ans 后,也就不需要再去尝试 ans+1 了。
def mySqrt(x: int) -> int:
# 初始化左右指针
l = 0
r = x
# 迭代直到左指针大于等于右指针
while l <= r:
# 计算中间索引
mid = (l + r) // 2
# 如果中间索引的平方小于等于输入值
if mid * mid <= x:
# 递增左指针
l = mid + 1
# 否则
else:
# 递减右指针
r = mid - 1
# 返回右指针,即二分查找的结果
return r
3,例二(leetcode:74. 搜索二维矩阵)
3.1,题目描述
给你一个满足下述两条属性的 m x n 整数矩阵:
每行中的整数从左到右按非严格递增顺序排列。
每行的第一个整数大于前一行的最后一个整数。
给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false 。
示例 1:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true
示例 2:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
输出:false
3.2,解题思路
def searchMatrix(matrix, target: int) -> bool:
m = len(matrix)
n = len(matrix[0])
# 遍历每一行
for i in range(m):
# 二分查找
left, right = 0, n - 1
while left <= right:
mid = (left + right) // 2
if matrix[i][mid] == target:
return True
elif matrix[i][mid] < target:
left = mid + 1
else:
right = mid - 1
return False
if __name__ == '__main__':
print(searchMatrix([[1,3,5,7],[10,11,16,20],[23,30,34,50]], 3))
print(searchMatrix([[1,3,5,7],[10,11,16,20],[23,30,34,50]], 13))

2万+

被折叠的 条评论
为什么被折叠?



