今天是释然发题解的第八天,以后每一天都会和大家分享学习路上的心得,希望和大家一起进步,一起享受coding的乐趣。
本文约1200字,预计阅读3分钟
n天前我们学习了链表,忘记的小伙伴们可以看一下哦:
今天我们来聊一聊的二分的相关问题,明天和大家分享分治的相关知识:
什么是二分
举一个简单的例子:
比如说我心中想一个数为888,让你猜这个数,这个数是在1到1000范围之间,尽可能少的次数猜出这个数字:
我们不可能从1开始猜,这样要猜888次。有些人从整百开始猜呀,100、200一直到800要猜8次,有些人意识到这个时候可以从850开始猜。
其实一开始就应该二分区间去猜测:大于500嘛?是。大于750嘛?是
大于875嘛?是,小于932.5嘛?是。小于903.25嘛。。。。。
不停地二分去查找这个数,时间复杂度会降低到logn
而上面这个例子用的就是二分的思想
二分查找
根据上面的思想,我们很容易写出:
//查找数组中是否存在与num相等的元素
int Binarysearch(*a,length,num)
{
int l=0,r=length-1,mid;
while(l<r)
{
mid=(l+r)/2;
//建议写成l+(r-l)/2否则可能会溢出
if(a[mid]==num)
{
return mid;
}
else
{
if(a[mid]>num)
{
r=mid;
}
else l=mid+1;
}
}
return -1;
}
//查找区间范围内中第一个大于等于num元素的下标
int lowerbound(a,a+length,num)
{
int l=0,r=length-1,mid;
while(l<=r)
{
mid=l+(r-l)/2;
if(a[mid]>=num)
{
r=mid;
}
else
{
l=mid+1;
}
}
return right;
}
我们不容易看出,二分查找需要查找的数据按照一定的顺序排列,也就是说对于无序的数据,我们先要用nlogn的复杂度去排序,查找需要用nlogn的时间,因此最终复杂度还是nlogn
C++中的lower_bound( )和upper_bound( )函数
详见这篇文章,作者写的很清楚:
https://blog.csdn.net/qq_40160605/article/details/80150252
好了,今天的有关二分查找的知识就到这里
释然每天发布一点自己学习的知识,希望2年后我们也能在ACM的赛场上见面,一起去追寻自己的程序猿之路吧!
后期也会和大家一起分享学习心得和学习经验呢,明天我们不见不散哦!
下期预告:
二分的相关题目
如果大家有什么建议或者要求请后台留言,释然也想和大家一起进步呀!
联系方式:shirandexiaowo@foxmail.com