二分查找法理论
使用场景
若数据是有顺序的,且数据中无重复元素,需要查找元素,第一时间就应该想起二分查找法
这里的有顺序不是指必须按升序或降序的顺序排列。 非降序、非升序、或部分有序的情况也是适用的
方法原理
二分法有两种写法,主要区别在于区间的定义,一种是左闭右闭,即[left, right],另一种则是[left, right)
要在二分查找的过程中,在while寻找中每一次边界的处理都要坚持根据区间的定义来操作
这里以704. 二分查找为例说明:
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 41. 二分法写法1(左闭右闭)
```python class Solution: def search(self, nums: List[int], target: int) -> int: left, right = 0, len(nums) - 1 # 位置1
while left <= right: # 位置2
mid = left + (right - left) // 2
if nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1 # 位置3
else:
return mid
return -1 ```
2.二分法写法2(左闭右开)
class Solution:
def search(self, nums: List[int], target: int) -> int:
left,right =0, len(nums) # 位置1
while left < right: # 位置2
mid = (left + right) // 2
if nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid # 位置3
else:
return mid
return -1
总结:
- 两种写法中,有3个位置写法不同
- 位置1:定义区间,写法1定义左闭右闭区间,写法2定义左闭右开
- 位置2:结束条件,写法1左右指针可以取到同一个值,写法2则取不到同一个值
- 位置3:定义右区间界限,写法1右区间可以取到mid - 1,写法2则取不到mid
- 注意mid计算时的写法,注意防止mid计算溢出,left + (right - left) / 2比(right + left) / 2更安全,且前者有效避免溢出
- 对于向上或向下取整问题,可参考69. Sqrt(x)解答