hello, everybody! 大家好 我是张张不吃香菇 这是我发布的第一篇作品(兼笔记)
本期笔记我将带领大家一起从对 二分 从0基础到入门,废话不多说,直接开始我们今天的学习~
(可以给个关注吗)
什么是二分?
在一个单调有序的集合或函数中查找一个解,每次分为左右两部分,判断解在哪个部分中并调整上下界,直到 找到目标元素,每次二分后都将舍弃一半的查找空间(对半砍价)。
什么时候用二分法?
二分的基本用途是在单调序列或单调函数中作查找操作,因此当问题的答案具有单调性时,就把求解转化为判定(判定的难度小于求解,因此时间复杂度低)。
什么是单调性?
是不是看了刚才两段话后有点懵? (单调性是啥子)那就对了! 因为我学的时候也很懵。这就来解释:单调性是指函数在自变量增加或减少的过程中,函数值的变化方向呈现出一致性的倾向。具体地说,若函数随着自变量的增加而单调递增,或者随着自变量的减少而单调递减,则认为函数具有单调性。反之,如果函数在某一段自变量区间内先递增后递减,或者先递减后递增,则该函数是非单调的。(重点)(看了不懂可以反馈给我,如果不懂的人多就单出一期)
二分的思想及时间复杂度?
二分算法的时间复杂度为 O(log n),比线性搜索算法的时间复杂度 O(n)更快,因此二分算法在数据量较大时具有很高的效率!!(为二分点赞)
- 初始化左右边界,即整个数据范围。
- 确定中间位置,将数据范围二分为左右两个子范围。
- 判断目标数据所在的子范围,如果目标数据在左边则在左子范围内做二分,否则在右子范围内做二分。
- 不断重复步骤3,直到找到目标数据或者整个数据范围缩小到极限。
while(l < r){
int mid = (l + r) >> 1;//mid = (l + 2) / 2;(向下取整)
if(a[mid] >= x){
r = mid;
}else {
l = mid + 1;
}
}
return a[l];
stl中 的二分查找
upper_bound(必会)
upper_bound(begin, end, num)会从从数组的begin位置到end-1位置查找第一个大于num的数字的位置(不存在则返回-1)注意,这个函数返回的是一个地址,即num在数组中的位置,如需num在数组中的下标,可以用返回的地址减去起始位置,得到num在数组中的下标。用例:
#include<bits/stdc++.h>
using namespace std;
int main(){
int num[6] = {1,2,4,7,15,34};
sort(num, num + 6);
int pos = upper_bound(num, num + 6, 7) - num;
cout << pos << " " << num[pos] << endl;
}
//输出:4 15
lower_bound(必会too)
lower_bound(begin, end, num)会从从数组的begin位置到end-1位置查找第一个大于等于num的数字的位置(不存在则返回-1)(注意的地方与upper_bound相同) 用例:
#include<bits/stdc++.h>
using namespace std;
int main(){
int num[6] = {1,2,4,7,15,34};
sort(num, num + 6);
int pos = lower_bound(num, num + 6, 7) - num;
cout << pos << " " << num[pos] << endl;
}
//输出:3 7
好了,这期讲解就到这里,如需了解后续,下期不见不散~ 下期带你一起了解二分答案和做有关二分法的题(详解)
(写了这么多,给个关注,下期将持续更新)
我是张张不吃香菇,我们下期再见,88~