- 1
- 0
- 约7.02千字
- 约 7页
- 2022-10-13 发布于湖北
- 举报
[算法总结]⼆分查找
本⽂⾸发于我的个⼈博客:尾尾部落
⼆分查找法作为⼀种常见的查找⽅法,将原本是线性时间提升到了对数时间范围,⼤⼤缩短了搜索时间,但它有⼀个前提,就是必须在有序数据中
进⾏查找。
⼆分查找很好写,却很难写对,据统计只有10%的程序员可以写出没有bug的的⼆分查找代码。出错原因主要集中在判定条件和边界值的选择
上,很容易就会导致越界或者死循环的情况。
下⾯对⼆分查找及其变形进⾏总结:
1. 最基本的⼆分查找
public int binarySearch(int[] A, int target, int n){
int low = 0, high = n, mid;
while(low = high){
mid = low + (high - low) / 2;
if(A[mid] == target){
return mid;
}else if(A[mid] target){
high = mid - 1;
}else{
low = mid + 1;
}
}
return -1;
}
其中,有⼏个要注意的点:
1. 循环的判定条件是: low = high
2. 为了防⽌数值溢出, mid = low + (high - low)/2
3. 当 A[mid] 不等于 target 时, high = mid - 1 或 low = mid + 1
leetcode参考 :Search Insert Position
2. 查找 ⽬标值 区域的左 边界/查找与⽬标值相 等的第 ⼀个位置 /查找 第 ⼀个不⼩ 于 ⽬
标 值数的位置
A = [1,3,3,5, 7 ,7,7,7,8,14,14]
target = 7
return 4
public int binarySearchLowerBound(int[] A, int target, int n){
int low = 0, high = n, mid;
while(low = high){
mid = low + (high - low) / 2;
if(target = A[mid]){
high = mid - 1;
}else{
low = mid + 1;
}
}
if(low A.length A[low] == target)
return low;
else
return -1;
}
3. 查找⽬标值区域的右边界/查找与⽬标值相等的最后⼀个位置/查找最后⼀个不⼤
于⽬标值数的位置
A = [1,3,3,5,7,7,7, 7 ,8,14,14]
target = 7
return 7
public int binarySearchUpperBound(int[] A, int target, int n){
int low = 0, high = n, mid;
while(low = high){
mid = low + (high - low) / 2;
if(target = A[mid]){
low = mid + 1;
}else{
high = mid - 1;
}
}
if(high = 0 A[high] == target)
return high;
else
return -1;
}
此题以可变形为 查找第⼀个⼤于⽬标值的数/查找⽐⽬标值⼤但是最接近⽬标值的数 ,我们已经找到了最后⼀个不⼤于⽬标值的数,那么再往后进⼀位,返
回 high + 1 ,就是第⼀个⼤于⽬标值的数。
剑指offer:数字在排序数组中出现的次数
4. 查找最后⼀个⼩于⽬标值的数/查找⽐⽬标值⼩但是最接近⽬标值的数
此题以可由第 2 题变形⽽来,我们已经找到了⽬标值
原创力文档

文档评论(0)