二分查找&二分答案

原创建时间:2018-02-06 16:48:20

\(O(\log_2n)\)的优秀算法

二分查找

百度百科原话

二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

二分查找的时间复杂度是\(O(log_{2}n)\)

要求

  • 查找的序列必须采用顺序存储结构
  • 查找的序列必须是有序排列的

思路

  1. 将需要查找的序列进行排序(一般为升序排列)
  2. 将序列中间位置记录的元素与关键字比较
  3. 如果相等,则返回查找成功
    如果不相等,则将序列分成左右两个子序列,若元素小于关键字,就到左子序列中查找;否则就到右子序列中查找

代码实现

#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;
}

二分答案

看完了二分查找,你会发现二分并没有什么卵用。

对,大部分情况二分的确没有什么用,但是从它身上衍生出来的二分答案却是一个很有用的东西!

二分答案,就是通过二分的方式枚举出一个答案来,然后再验证你的查找结果是否正确,从而获取答案

要求&特点

  1. 答案具有单调性
  2. 题面里包含与“最小的最大,最大的最小”相关的字眼

思路

  1. 先将给定的序列排序
  2. 参照二分查找,枚举一个答案mid
  3. 验证这个答案是否可行
  4. 如果可行,更新边界,找寻更佳答案
    如果不可行,更新边界,继续寻找答案

代码实现

一般模板

其中的check函数需要针对每一个题目进行验证

当然你会写暴力枚举的check也可以借鉴过来#(滑稽)

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
inline bool check(int x){
  /* code here*/
  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;
}

推荐题目

  1. 「洛谷P2678 跳房子」 出处:NOIP2015 提高组
  2. 「洛谷P1824 进击的奶牛」 出处:USACO

原文地址:https://www.cnblogs.com/handwer/p/11745266.html

时间: 2024-08-02 11:50:05

二分查找&二分答案的相关文章

二分查找&amp;&amp;二分中位数

普通二分查找 1 int bs(int L,int R,int x) 2 {//在l到r区间上查找x,找不到就返回-1 3 int l=L,r=R; 4 while(l<=r){ 5 int m=l+r>>1; 6 if(a[m]==x){ 7 return m; 8 } 9 else if(a[m]>x){ 10 r=m-1; 11 } 12 else{ 13 l=m+1; 14 } 15 } 16 return -1; 17 } 普通版很简单就不详细总结了 二分查找中位数 题意

二分查找实现

二分查找 二分查找的前提是数组必须有序.这个算法据某本说,百分之九十的都会写错.编写程序需要注意的是 非法输入 尽量使用迭代,因为如果数组很大的话,递归有可能是栈溢出 循环判断条件 注意mid的求值方法,mid = ((right - left) >> 1) + left ;可以防止两个整型值相加时溢出.并注意>>运算符优先级低于+ - * / %,所以要对左移右移加括号.如果没有加括号,得出的答案是错误的.比如:2 >> 1 + 2 你试下打印出来是多少. 数组里的数

【leetcode边做边学】二分查找应用

更多请关注我的HEXO博客:http://jasonding1354.github.io/ 简书主页:http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles 二分查找 二分查找算法是一种在有序数组中查找某一特定元素的搜索算法.搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束:如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较.如果在某一步骤数组 为

浅谈二分和二分答案

一般来讲我们会在以下情况用到二分: 求单调函数的零点 求一堆东西的最小值最大是多少 很难直接算出答案,但是很好判定答案合不合法 如果想学就继续看吧! 二分查找 二分是一种可以再\(\mathcal{O}(\mathrm{ch}\log m)\)(\(m\)为数据规模,\(\mathrm{ch}\)为判断状态合法性check()函数时间复杂度)时间复杂度内求解问题的方法,主要是一个分治,每次将搜索范围减半. 我们以二分查找引入. 有一个有序序列,二分查找的思想如下: 1.定义L,R,mid代表答案

python函数:递归函数及二分查找算法

本文和大家分享的主要是python的递归函数及二分查找算法相关内容,一起来看看吧,希望对大家学习python有所帮助. 一.递归的定义 def story(): s = """ 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? """ print(s) story() story() 老和尚讲故事 递归的定义 -- 在一个函数里再调用这个函数本身.这种魔性的使用函数的方式就叫做 递归 . 递归的最大深度:997 1.python递归最大层

【Java_Base】常用查找算法:顺序查找、二分查找

顺序查找 从第一个元素开始顺序比较查找. 二分查找 二分查找前提条件: 已排序的数组中查找 二分查找的基本思想是: 首先确定该查找区间的中间点位置: int mid = (low+upper) / 2; 然后将待查找的值与中间点位置的值比较: 若相等,则查找成功并返回此位置. 若中间点位置值大于待查值,则新的查找区间是中间点位置的左边区域. 若中间点位置值小于待查值,则新的查找区间是中间点位置的右边区域. 下一次查找是针对新的查找区间进行的. 1 public class Search{ 2 p

Java数组二分查找

二分查找法一般指二分查找 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找

查询资料:二分查找法

二分查找 编辑 同义词 二分查找法一般指二分查找 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到

查找 —— 二分查找[递归+非递归]

二分查找 二分查找是对一组有序序列进行查找.根据要查找的k和序列中间元素比较,动态的移动查找范围.以对折的方式缩小查找范围. 递归方式: def binarySearch(A,left,right,k): if left<= right: mid =(left+right)//2 if A[mid] == k: return mid if A[mid]>k: return binarySearch(A,left,mid-1,k) #此处要返回函数运行结果而不是仅仅调用函数 else: retu