`
wangminshe89
  • 浏览: 667866 次
文章分类
社区版块
存档分类
最新评论

查找集合中两个最大的元素

 
阅读更多

查找集合中两个最大的元素

启示:我们应该仔细检查证明过程中是否确实用到了所有的假设;应该设法用更少的假设完成同样的证明;另外,除非有反例说明已经到达所有可能的证明的边界,否则我们应该永不满足。

———Polyaand Szego[1927]

消除非实质性的假设有时能够得到更好的算法,不必要的假设有时意味着证明可能存在错误。

问题:已知集合S有n个元素x1,x2,….xn,求其中最大的和第二大的元素。

分析:我们要尽可能的减少比较次数,为简单起见,设n为2的幂。

分治:把S分成大小为n/2的两个子集P和Q。如果现在直接进行归纳,则假设已知P和Q中的最大和第二大的元素,分别记为p1,p2和q1,q2,然后查找S中的最大和第二大的元素。很明显,两次比较足以找到S中的这两个元素。第一次比较最大数p1和q1,此时得到一个新的第二大的数,这个数与原来的第二大的数(P或Q中的一个)比较一次,记为所求(比较过程见下图)。用这种方法得出递归关系T(2n)=2T(n)+2及T(2)=1,解得T(n)=3n/2-2。尽管这要优于直接进行的2n-3次比较,但算法还是可以在改进的。不是每一次找到的最大第二大元素都是有效的,只有到算法的最后我们才能确定最大元素和第二大元素。

仔细分析上图的比较,可以看出算法不再使用q2,故q2的计算是多余的。如果能精简这样的计算,就可以进一步减少比较次数。然而,在p1和q1比较前,我们并不清楚p2和q2中的哪一个可以不必考虑,如果知道那个子集会“失败”,那么就可以在这个子集上用常规的查找最大数的算法了,这还能省去不少比较。看来我们已经意识到有些比较可以避免,只是不清楚究竟哪些可以忽略,那应该怎么做?

技巧:所以把第二大元素的计算推迟到算法的最后,只保留第二大元素的候选者列表。

归纳(第二次):给定一个小于n的集合,知道如何找到最大的元素以及第二大元素的一个“短短的”候选者列表。

短短的到底有多长尚未定义,但在算法设计过程中,我们会找到一个合适的值。

算法:给定大小为n的集合S,把它分为大小为n/2的字迹P和Q。由归纳假设可知两个集合最大的几个元素是p1和q1,在加上第二大元素的候选者集合Cp和Cq。首先比较p1和q1,取其中大者。例如p1作为S的最大数,然后舍去Cq,因为Cq中的所有元素都小于q1,接着再把q1加入Cp中。最终我们得到了一个最大的元素和一个候选者集合,从中可以直接选出第二大的数。查找最大数所需的比较次数满足递归关系T(n)=2T(n/2)+1及T(2)=1,解得T(n)=n-1。很容易看到,扩大一倍集合的大小时,我们能在候选者集合中再加入一个元素,所以lbn足以满足候选者集合大小的需要。于是查找第二大元素需要lbn-1次额外比较,因而总比较次数为n-1+lbn-1,恰为最可能的次数。n为2的幂时的归纳假设如下:

归纳(第三次):给定一个小于n的集合,知道如何求出最大的元素和第二大的元素的候选者集合,这个集合自多不超过lbn个元素。

参考代码:

总结:如何改进一个算法,首先要看到这个算法的缺点,有时候在脑子里面运行一遍这个程序,缺点就暴露出来了。所以有必要检查是否存在对最终结果不起作用的部分,这些部分往往可以被删除,即使不能被删除,也可以用更简单、效率更高的运算代替。

分治算法会产生一些中间结果,并不是这些中间结果都对我们的最终结果有所帮助。


分享到:
评论

相关推荐

    用顺序表完成2个集合的交集与并集以及各个集合的情况

    1.有序顺序表的元素按照从小到大有序存储; 2.实现有序顺序表的类模板,它的操作如下: ...3.用有序顺序表表示集合,实现两个有序顺序表的并和交(并和交仍是有序顺序表)并分析它们的时间复杂度;

    求2个集合的交集

    对于给定的两个集合,使用哈希表可以在线性时间复杂度内得到他们的交集和并集,具体说明如下: 假设有集合A={1, 7, 5, 13, 9, 10, 11}, B={5, 7, 10, 1, 18, 12}, 1)求交集,需要得到结果:A∩B={1, 5, 7,10} 思路...

    测量程序编制 - python 50数据类型:Set(集合)-差集.pptx

    set1 -- 必需,要查找相同元素的集合 set2 -- 必需,可以是任何序列,可以多个,多个使用逗号 , 隔开 若是字典,按键比较 返回值:返回一个新的集合 set1={1,2,3} set2={3,4,5,2} list1=[2,3] dict1={2:9,'b':10} ...

    给n个整数的集合s和一个整数x,判断是否存在两个数的和为x

    算法课本的题目,要求复杂度是(nlgn)。

    数据结构实验

    如何利用二分查找算法在一个有序表中插入一个元素x,并保持表的有序性? 实验7:至少三种排序算法的程序实现 (第十六周星期三7、8节) 一、 实验目的 1.掌握简单插入排序、冒泡排序、快速排序、堆排序以及归并...

    集合合并与查找-并查集

    分离集合(disjoint set)是一种经典的数据结构,它有三类操作: Make-set(a):生成包含一个元素a的集合S; Union(X, Y):合并两个集合X和Y; Find-set(a):查找元素a所在集合S,即通过元素找集合句柄;

    Intersect2:查找多个(多于两个)数组的交集(公共元素)-matlab开发

    在 MATLAB 中,有一个命令叫做“intersect”,它可以找到两个向量的集合交集(公共元素)。 但是,如果我想比较两个以上的向量并找出它们的交集,则此命令不起作用。 因此,我决定编写这个名为“intersect2”的函数...

    Link1_链表指针_

    创建链表,插入,删除。求两个集合的合并运算编程实现两个集合的并运算,即A=A∪B,要求分别采用数组与...解决该问题,可以从集合B中依次取得每个数据元素,将其中在集合A中依次查找,若不存在则在A集合中插入该元素。

    【Python入门教程】第48篇集合的对称差集.pdf

    集合的对称差集 两个集合的对称差集包含了两个集合中不属于两者交集的所有元素。以下是集合 s1 和 s2: s1 和 s2 的对称差集返回结果如下: 从以上结果可以看出,所有元素属于 s1 或者 s2,同时⼜不属于它们的交集...

    JQuery元素快速查找与操作

    首先,我们来看看jquery中如何查找到想要的结点。 第一步:sizzle选择器 基于元素的id、类、类型、属性、属性值...返回介于两个给定元素之间的所有祖先元素,下面是例子: $(document).ready(function(){ //会返回sp

    测量程序编制 - python 51数据类型:Set(集合)-对称差集.pptx

    2) symmetric_difference()方法:返回两个集合中不重复的元素集合,即会移除两个集合中都存在的元素 语法: set. symmetric_difference(set1, set2 ... etc) set1 -- 必需,要查找相同元素的集合,可以是任何序列 ...

    Python cookbook(数据结构与算法)实现查找两个字典相同点的方法

    本文实例讲述了Python实现查找两个字典相同点的方法。分享给大家供大家参考,具体如下: 问题:寻找两个字典中间相同的地方(相同的键、相同的值等) 解决方案:通过keys()或者items()方法来执行常见的集合操作...

    hyperdiff:查找两个集合之间的公共,已删除和已添加元素

    查找两个集合之间的公共,已删除和已添加元素。 安装 $ npm install hyperdiff --save 用法 使用平面Array : const diff = require ( 'hyperdiff' ) var result = diff ( [ 1 , 2 , 3 , 4 , 5 , 6 ] , [ 1 , 2 ...

    并查集(Union-Find)介绍.zip

    并查集,并查集算法的基本思想是通过维护一个父节点数组来实现元素的分组。初始时,每个元素的父节点都是自己。...在查询两个元素是否属于同一个集合时,可以通过查找它们的根节点是否相同来判断。

    数据结构实验一(顺序表基本操作)题目和源程序

    实验内容: 1.编写程序实现顺序表的下列基本操作: (1)初始化顺序表La。 (2)将La置为空表。 (3)销毁La。 ...(3)假设两个顺序线性表La和Lb分别表示两个集合A和B,利用 union_Sq操作实现A=A∪B。

    并查集主要操作及主要操作.docx

    - 查找某个元素所属的集合,通常通过找到集合的代表元素来判断两个元素是否属于同一个集合。 3. **合并(Union):** - 将两个不同的集合合并成一个集合,通常选择其中一个集合的代表元素作为新的集合的代表。 #...

    整数分区:查找包含同构元素的集合的所有分区,也称为整数分区。-matlab开发

    这类似于在交换中提交“24185-partitions”,但集合包含相同的元素。 分区也是一种将输入 n 写为正整数之和的方法。 可以提供可选参数 s 以输出部分数小于或等于 s 的分区子集。 划分方式的数量是按顺序排列的...

    C#,图论与图算法,无向图(Graph)回环(Cycle)的不相交集(disjoint)或并集查找(union find)判别算

    这可用于确定两个元素是否在同一子集中。 并集:将两个子集合并为一个子集。这里我们首先要检查这两个子集是否属于同一个集合。如果没有,那么我们就不能执行联合。 在这篇文章中,我们将讨论不相交集数据结构的...

    Leetcode 并查集详解

    当两个集合合并时,将其中一个集合的根节点指向另一个集合的根节点。 基于秩的优化:为了避免树形结构的不平衡,可以使用秩(rank)来表示树的高度或大小。将秩较小的树合并到秩较大的树上,以保持树的平衡。这样...

Global site tag (gtag.js) - Google Analytics