1.二分查找框架
int binarySearch (int[] nums, int target){
int left = 0;
int right = ...;
while (left < right){
int mid = left + (right - left) / 2;
if (nums[mid] == target){
...
} else if (nums[mid] < target){
left = ...
} else if (nums[mid] > target){
right = ...
}
}
}
分析二分查找的技巧:
- 不要出现
else
,而是要把所有情况用else if
写清楚,这样可以清晰展现所有细节 - 计算mid时需要防止溢出。上面代码中
left + (right - left) / 2
和(left + right)/2
结果相同,但有效防止了left
和right
太大直接相加导致溢出。
寻找一个数(基本的二分查找)
function binarySearch (nums, target){
let left = 0
let right = nums.length - 1 // 注意
while (left <= right){
let mid = left + (right - left)/ 2;
if (nums[mid] === target){
return mid
} else if(nums[mid] < target){
left = mid + 1 // 注意
} else if (nums[mid] > target){
right = mid -1 // 注意
}
}
}
1. while中是<=,而不是<
在上面代码中,right的初始值为nums.length-1
,是最后一个元素的索引,而不是nums.length。
这两者看似一致,但实际有区别:
right初始化为nums.length-1
,相当于查找的区间是闭区间[left, right]。
而right初始化为nums.length
,查找的区间就变成左闭右开了[left,right)
,因为nums.length
是越界的。
搜索停止的条件是nums[mid]===target
。但如果没找到,就当搜索区间为空时,跳出while循环。