二分初学总听到说简单的话。
说简单的话就真的是我学得少,二分其实是很巧妙的,很深的,还有很多需要我去学。
这次周赛里有一道二分题目,可怜我当时并没有考虑清楚这个道题目的二分。所以还是太菜了,(留下不争气的眼泪 jiayouba
还是来理解一下二分:
二分是建立在有单调性才会去使用的。
简单举个例子:用二分找一个数
每次拿出序列中间的数并和目标数字进行比较,会有三种情况:
1.这个数恰好等于目标数字,找到了,返回这个数的下标index。
2.这个数比目标小说明目标在右半边的序列中,淘汰掉左半边。
3.这个数比目标大说明目标在左半边的序列中,淘汰掉右半边。
当出现2、3这两种情况时,我们就在对应的半边序列中递归地重复上述判断,直到这半边的序列为空位止,这时就说明序列中并没有对应的数字,直接返回当前的index。
ll erfen(ll x,ll da)
{
ll l=1,r=x;
while(l<=r)
{
ll mid=(l+r)>>1;
if(num[mid]==da)
{
return mid;
}
else if(num[mid]>da)
r=mid-1;
else
l=mid+1;
}
return l;
}
写这个二分还要考虑一些细节:
比如
1.为什么while(l<=r)而不是l<r,这时候就用极端去考虑,因为序列里只有一个1时,l=r=1,那么就会进不了while。
2为什么不相等后 r 和 l 的值不是赋值成 mid,或者其它,而是要 -1 和 +1 呢?如果不相等,说明无轮如何 nums[mid] 都不应该被包含进下一轮的判断,所以才通过 -1 和 +1 来将其砍掉。
当然二分还有其它变种以及函数和许多不同题目不同用法,所以,我希望下一阶段要深学这一个方面的知识点。