代码随想录算法训练营第1天|数组Part01
给定一个
n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果target存在返回下标,否则返回-1。 你必须编写一个具有O(log n)时间复杂度的算法。
二分查找的前提条件
- 数组有序
- 无重复元素
循环不变量原则
二分法的核心是:始终保持区间定义的一致性(即循环不变量)。
常见区间定义有两种:
1. 左闭右闭区间 [left, right]
- 循环条件:
while (left <= right) - 中点计算:
const mid = left + ((right - left) >> 1) - 边界收缩方式:
- 若
nums[mid] > target:排除右侧 →right = mid - 1 - 若
nums[mid] < target:排除左侧 →left = mid + 1
- 若
2. 左闭右开区间 [left, right)
- 循环条件:
while (left < right) - 中点计算:
const mid = left + ((right - left) >> 1) - 边界收缩方式:
- 若
nums[mid] > target:排除右侧 →right = mid - 若
nums[mid] < target:排除左侧 →left = mid + 1
- 若
正确代码示例(左闭右闭区间)
1 | var search = function(nums, target) { |
关键总结
区间定义决定一切:
[left, right]对应while (left <= right)[left, right)对应while (left < right)
始终保证循环内
mid落在合法区间中- 推荐统一使用:
mid = left + ((right - left) >> 1)
- 推荐统一使用:
防止死循环
- 每次循环要收缩区间
- 切忌写错为
right = mid(在[left, right]情况下会死循环)
为什么向下取整?
- 保证
mid不越界 - 保证区间逐步缩小
- 提高计算效率(避免函数调用)
- 保证