O(\log_2n)
的优秀算法
二分查找 百度百科原话 1 二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
二分查找的时间复杂度是
O(log_{2}n)
要求
思路
将需要查找的序列进行排序(一般为升序排列)
将序列中间位置记录的元素与关键字比较
如果相等,则返回查找成功
如果不相等,则将序列分成左右两个子序列,若元素小于关键字,就到左子序列中查找;否则就到右子序列中查找
代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> #include <cstdio> #include <cstring> using namespace std ;inline bool BinarySearch (int l,int r,int t,int x[]) { while (l <= r){ int mid = (l + r) >> 1 ; if (x[mid] == t) return true ; if (x[mid] < t) l = mid + 1 ; if (x[mid] > t) r = mid - 1 ; } if (l > r) return false ; }int main () { int dest; cin >> dest; int n; cin >> n; int *p = new int [n + 1 ]; for (int i = 0 ;i < n;i++) cin >> p[i]; printf ("%s\n" ,BinarySearch(0 ,n - 1 ,dest,p)?"YES" :"NO" ); return 0 ; }
二分答案 看完了二分查找,你会发现二分好像只能用来在有序数列里找数。
对,一些情况二分只能拿来找数,但是从它身上衍生出来的二分答案却是一个很有用的东西!
二分答案,就是通过二分查找的方式枚举出一个答案来,然后再验证你的查找结果是否正确,从而获取答案
要求&特点
答案具有单调性
题面里包含与“最小的最大,最大的最小”相关的字眼
思路
先将给定的序列排序
参照二分查找,枚举一个答案mid
验证这个答案是否可行
如果可行,更新边界,找寻更佳答案
如果不可行,更新边界,继续寻找答案
代码实现 一般模板
其中的check函数需要针对每一个题目进行验证
当然你会写暴力枚举的check也可以借鉴过来#(滑稽)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iostream> #include <cstdio> #include <cstring> using namespace std ;inline bool check (int x) { return true ; }int main (int argc, char const *argv[]) { int n,m; cin >> n >> m; int *p = new int [n + 2 ]; for (int i = 0 ;i < n;i++) cin >> p[i]; int l = 0 ,r = n - 1 ; int ans = 0 ; while (l <= r){ int mid = (l + r) >> 1 ; if (check(ans)){ l = mid + 1 ; ans = mid; } else r = mid - 1 ; } cout << ans << endl ; return 0 ; }
推荐题目
「洛谷P2678 跳房子」 出处:NOIP2015 提高组
「洛谷P1824 进击的奶牛」 出处:USACO