二分总结

二分分为二分查找和二分答案。

设数组下标为1~n

二分查找。实际上就是一个有序数列中有一个解,然后搜一遍求这个解。而直接for循环暴搜一遍的话时间复杂度是O(n),而用二分查找可以降低时间复杂度,为O(logn);而数组形象化出来的话就是0000010000000(0为无解,1为有解),二分就是要找中间的1,即为唯一解。所以开始l和r设为一定是无解的部分,代码如下。

int mid, l = 0, r = n + 1 //l = 数组最小下标-1,r = 数组最大下标+1
while(l + 1 < r)
{
	mid = (l + r) >> 1;
 	if(a[mid] == key) break;
 	if(a[mid] > key) r = mid; //key为要找的东西
 	else l = mid;
}
printf("%d\n", mid);

 

注:如果求函数解析式的值,只用改while条件是(r-l)< 题目最小精度再小两个精度

  

二分答案是二分查找的推广,即是有很多个解,然后寻找最优解。

一般求最大值就是就是1111100000000。此时r仍然是一定无解,而l则是一定有解的边界(即数组的最小下标),最后输出l

 最小值则返过来是00001111,此时l是无解,r是有解,最后输出r。

下面是1111000情况的代码 

int l = 1, r = n + 1 //l为最小解下标,r为无解下标 
while(l + 1 < r)
{
	int mid = (l + r) >> 1;
 	if(!check(mid)) r = mid; //表示mid不符合题目要求,无解
 	else l = mid;
}
printf("%d\n", l);

    

题目中的运用一般分三类

一是查找某个元素是否存在用二分优化复杂度(前提是有序,要先排序)

二是计算函数取值三是枚举最优解。这三种用法的写法有区别,要注意区分。

二分答案用的比较多,一般是在比较mid和key的地方做了手脚,根据题目写个check(mid)函数即可。

 

   

转载于:https://www.cnblogs.com/sugewud/p/9819320.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值