二分查找的基本思想
二分查找的核心思想是比较数组的中间元素与目标值。根据比较结果,可以排除一半的搜索空间。具体步骤如下:
初始化指针:设置两个指针,left 指向数组的开始位置,right 指向数组的结束位置。
循环搜索:当 left 指针小于等于 right 指针时,持续搜索。如果使用 left < right,可能会错过边界元素。
中点计算:计算中点 mid 的位置,这通常通过 (left + right) / 2 实现。
目标比较:比较中点元素 nums[mid] 与目标值 target:
如果相等,找到目标值,可直接返回位置。
如果 nums[mid] 小于 target,调整 left 指针到 mid + 1。
如果 nums[mid] 大于 target,调整 right 指针到 mid - 1。
结果返回:如果循环结束没有找到目标值,则处理未找到的情况,比如返回 -1 或者确定目标值应该插入的位置。
为何使用 left <= right 而非 left < right
在二分查找中使用 left <= right 是为了确保包括边界条件。例如,考虑数组 [1, 2, 3, 4, 5] 和目标值 5
如果使用 left < right,当 left 和 right 同时指向最后一个元素(也就是目标值)时,循环会结束,因为条件 left < right 不成立,从而导致无法检查最后一个元素。
使用 left <= right 确保在 left 和 right 相遇时仍会检查那个位置,避免漏掉可能的匹配。
为何使用 right = mid - 1 而非 right = mid
更新 right = mid - 1 是为了确保中点已经被检查并且不满足条件后,不再包含在新的搜索区间内。如果仅设置 right = mid,则中点未被排除,可能会导致无限循环。例如: 数组: [1, 3, 5]目标值: 2
代码实现
下面是二分查找的一个典型实现,使用 Java 语言:
class Solution {public int searchInsert(int[] nums, int target) {int left = 0, right = nums.length - 1;while (left <= right) {int mid = (left + right) / 2;if (nums[mid] == target) {return mid; // 找到目标值,返回索引} else if (nums[mid] < target) {left = mid + 1; // 搜索右半部分} else {right = mid - 1; // 搜索左半部分}}return left; // 处理目标值未找到的情况,返回应插入位置}
}
结论
二分查找是一种在有序数组中寻找特定元素的高效方法。正确理解并实现其中的边界条件和指针更新是关键