二分法详解

连续看我文章的朋友就会发现,我写文章有一个特点,总是用经典的例题引出一个方法,在之后的文章中才会介绍这种方法的详细信息。这样做的好处是:避免了先接触干巴巴的概念导致很多朋友看的时候会有索然无味这种体验,由具体题目的分析过程来一步一步优化,最终引出方法这种形式,更能让这种方法变得顺理成章,也更能让读者体会到方法的巧妙之处。这种由兴趣激发的探索的欲望对彻底掌握一种方法其实是比较重要的。直接去接触一种方法有可能目的只是学会,但是产生兴趣而去探索一种方法的始末才能真正了解、掌握甚至读懂其真正的奥秘所在。



下面,我将会给大家详细的介绍二分法的信息。

二分法起源于数学中找函数零点的问题:

对于区间[a,b]上连续不断且f(a)·f(b)<0的函数y=f(x),通过不断地把函数f(x)的零点所在的区间一分为二,使区间的两个端点逐步逼近零点,进而得到零点近似值的方法叫二分法。

如图所示,区间的端点为 A 点和 B 点,函数的图像在区间 AB 范围内是单调递增的,现在要找函数图像的零点 C 。由于这个图像比较特殊,区间 AB 的中点正好是 C 点,所以只需要第一次判断区间中心点就可以找到。假设 D 点是区间的中心,那么可以看出 区间 AD之间的函数值全部小于零,因此全部不满足条件,区间 DB中,函数连续且单调递增,左半边函数值小于零,右半边函数值大于零,那么在 DB 之间必然存在一个位置 使得函数值等于零。也就意味着以 D 点为分界,左半边 一定没有答案,右半边一定有答案。这样不断缩小区间,不断逼近,一定能让包含答案的区间长度足够小,比题目要求的精度还要小,这个时候,区间内的任意一个实数都可以作为答案。使用这种方法求函数零点的条件是:在区间范围内,函数图像连续且单调。

现在将这种二分的思想运用在程序设计中,也能产生神奇的效果。

之前在例题中,我使用二分法的情境是这样的:由于 循环要进行 1e18 量级的次数,会超时,因此我在寻求一种方法,能够减少循环执行的次数,这个时候题目隐含的条件是 天数和麻雀个数是在逐天增加,也就是题目所给的条件呈现出来的是线性的关系,在区间的中心位置取测试点,将区间一分为二,这时候必然能够肯定有一个区间里所有的数据均不满足条件,而另一区间存在数据能够达到条件。如此将区间不断等分,每次都能巧妙减少一半的数据量,只在符合条件的区间中查找,效率非常高。(没看过之前文章的朋友可能需要看过昨天的文章才能了解)

二分法的使用条件:

  1. 待查找的序列区间单调有序(单调递增或单调递减都可以)
  2. 待查找序列和题目的要求建立的函数关系单调有序

也就是说,在将区间一分为二后,答案只能出现在其中的一个区间,不能同时出现在两个区间内,这样的情形下才适合二分。如果不能保证这个条件,那就需要考虑别的方法。

二分法使用方法:

假设待查找序列和题目的要求之间的关系是单调递增的,先取区间的中心,判断该处函数值和题目标准值的大小关系,如果函数值偏小,那么应该在中心右侧的区间继续查找;如果函数值偏大 ,那么应该在中心左侧区间继续查找,直到找到对应的值或者区间缩小到左右端点之间不再包含其他数据结束。



二分的思想很重要,面对具体的情形需要做相应的变通。

时间: 2024-12-29 11:27:33

二分法详解的相关文章

java之二分法详解

废话不多说,先来程序.一步一步看注释, 首先要注意:使用二分法时,数组必须是有序的,也就是从大到小或者从小到大的,不能是无序的 public static int halfSearch(int[] arr,int key){             int min,max,mid;//分别为最小值,最大值,和中间值             min = 0;             max = arr.length - 1;             mid = (max + min)/2;//这应

深入MySQL用户自定义变量:使用详解及其使用场景案例

一.前言 在前段工作中,曾几次收到超级话题积分漏记的用户反馈.通过源码的阅读分析后,发现问题出在高并发分布式场景下的计数器上.计数器的值会影响用户当前行为所获得积分的大小.比如,当用户在某超级话题下连续第n(n即计数器的值)次进行转发帖子时,将会获得与n相关的分数.然而,在第一次改进后问题依然存在.所以,这次在之前的基础上,通过使用MySQL变量的途径来解决该问题. 二.到底MySQL的变量分哪几类? MySQL变量一共分为两大类:用户自定义变量和系统变量.如下: 用户自定义变量 局部变量 会话

iOS教程:详解iOS多图下载的缓存机制

ios教程,ios的干货一直来不及给大家分享,小编也是一直在忙啊!今天给大家献上ios:详解iOS多图下载的缓存机制 1. 需求点是什么? 这里所说的多图下载,就是要在tableview的每一个cell里显示一张图片,而且这些图片都需要从网上下载. 2. 容易遇到的问题 如果不知道或不使用异步操作和缓存机制,那么写出来的代码很可能会是这样: cell.textLabel.text = app.name; cell.detailTextLabel.text = app.download;NSDat

Python中的高级数据结构详解

这篇文章主要介绍了Python中的高级数据结构详解,本文讲解了Collection.Array.Heapq.Bisect.Weakref.Copy以及Pprint这些数据结构的用法,需要的朋友可以参考下 数据结构 数据结构的概念很好理解,就是用来将数据组织在一起的结构.换句话说,数据结构是用来存储一系列关联数据的东西.在Python中有四种内建的数据结构,分别是List.Tuple.Dictionary以及Set.大部分的应用程序不需要其他类型的数据结构,但若是真需要也有很多高级数据结构可供选择

Android ArrayMap源码详解

尊重原创,转载请标明出处    http://blog.csdn.net/abcdef314159 分析源码之前先来介绍一下ArrayMap的存储结构,ArrayMap数据的存储不同于HashMap和SparseArray,在上一篇<Android SparseArray源码详解>中我们讲到SparseArray是以纯数组的形式存储的,一个数组存储的是key值一个数组存储的是value值,今天我们分析的ArrayMap和SparseArray有点类似,他也是以纯数组的形式存储,不过不同的是他的

机器学习经典算法详解及Python实现--聚类及K均值、二分K-均值聚类算法

摘要 聚类是一种无监督的学习(无监督学习不依赖预先定义的类或带类标记的训练实例),它将相似的对象归到同一个簇中,它是观察式学习,而非示例式的学习,有点像全自动分类.说白了,聚类(clustering)是完全可以按字面意思来理解的--将相同.相似.相近.相关的对象实例聚成一类的过程.机器学习中常见的聚类算法包括 k-Means算法.期望最大化算法(Expectation Maximization,EM,参考"EM算法原理").谱聚类算法(参考机器学习算法复习-谱聚类)以及人工神经网络算法

机器学习经典算法详解及Python实现--CART分类决策树、回归树和模型树

摘要: Classification And Regression Tree(CART)是一种很重要的机器学习算法,既可以用于创建分类树(Classification Tree),也可以用于创建回归树(Regression Tree),本文介绍了CART用于离散标签分类决策和连续特征回归时的原理.决策树创建过程分析了信息混乱度度量Gini指数.连续和离散特征的特殊处理.连续和离散特征共存时函数的特殊处理和后剪枝:用于回归时则介绍了回归树和模型树的原理.适用场景和创建过程.个人认为,回归树和模型树

线段树详解 (原理,实现与应用)

线段树详解 By 岩之痕 目录: 一:综述 二:原理 三:递归实现 四:非递归原理 五:非递归实现 六:线段树解题模型 七:扫描线 八:可持久化 (主席树) 九:练习题 一:综述 假设有编号从1到n的n个点,每个点都存了一些信息,用[L,R]表示下标从L到R的这些点. 线段树的用处就是,对编号连续的一些点进行修改或者统计操作,修改和统计的复杂度都是O(log2(n)). 线段树的原理,就是,将[1,n]分解成若干特定的子区间(数量不超过4*n),然后,将每个区间[L,R]都分解为 少量特定的子区

Spring事务管理(详解+实例)

写这篇博客之前我首先读了<Spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都