于每次查找,都会使得查找区间缩减为原来的一半,即如果查找区间为1024,只需要10次查找即可得到结果。
即不论查找是否成功,该算法的查找次数一定是O(logn)级别,因此时间复杂度为O(logn)。
模板
关于二分查找的模板有很多种,多为区分不同情况来使用不同的模板,个人感觉很容易用错。这里只推荐下面这一种,只有这一套模板,完全不需要担心用错或者记错,相关细节都标注在算法代码中。
int search(int tar) {
int l=1, r=n, mid, ans = -1;//四个固定变量,其中ans先赋值为非法值
while(l<=r) {// 模板内固定写法,不需要变
mid = (l+r)/2;// 模板内固定写法,不需要变
if(a[mid] == tar) ans = mid;// 找到答案后更新答案,根据具体题目决定是return,还是更改L或R后继续查找
else if(a[mid] < tar) L = mid+1;// 在L=mid+1或R=mid-1中根据题意选一个,并根据题目自行决定是否需要记录ans
else R = mid-1;// 在L=mid+1或R=mid-1中根据题意选一个,并根据题目自行决定是否需要记录ans
}
return ans;
}
在上述模板中,大多数行都是不需要改动的,L=mid+1和R=mid-1也是两个固定搭配,代表两个相反的方向,做题时带入两个具体数字判断一下选哪个方向即可。(有的模板中可能一会儿R=mid一会儿R=mid-1的,个人感觉很容易混淆)
模板中,只有5,6,7三行是有可能改动的(有的题目计算较为复杂,可能要抽个check函数出来判断),具体题目中的写法思路也很清晰:先把if条件都列出来,然后每个条件分支后的语句在
ans = mid
L=mid+1
R=mid-1
三个中选择一个或两个即可。(注意有可能选择两个哦,下面有例题)
浙公网安备 33010602011771号