Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 软件时空 > 软件相关 > 在集合中查找两数之和等于x的三种方法
【标  题】:在集合中查找两数之和等于x的三种方法
【关键字】:
【来  源】:http://www.cublog.cn/u/23052/showart.php?id=164420

在集合中查找两数之和等于x的三种方法

Your Ad Here

这只是一道书本上的简单练习题.

这里列出了三种方法,其中方法一是最原始的方法O(n^2),方法二是书上的标准答案O(nlgn),方法三是我做题时用的方法O(n)。

原始题目如下:Given a set S of n integers and another integer x, determine whether or not there exist two elements in S whose sum is exactly x.

 

大概意思就是:给定含n元素的集合S和整数x,判断集合S中是否有两个数的和恰好等于x.

 

稍微精确一点就是:设有集合S{a1,a2,…,an}和整数x,试问能否在S中找到ai和aj( 0<i<j<n+1 ),使得 ai + aj = x ?
 

方法一:

用最原始的两层循环搜索办法,worst case时间复杂度为O(n^2)


方法二:

    O(n)+O(n)+…+O(n)不会超过O(n)

    O(nlgn)+O(nlgn)+O(nlgn)不会超过O(nlgn)

    由于在n->∞的时候O(nlgn)的算法会比O(n^2)算法速度快,所以可以考虑采取”人海战术”,在S上顺序地多跑几次O(nlgn)的算法,能否解决问题?

    设有ai、aj( 1<= i!= j <=n ) ∈S , 且ai + aj = x ,则 aj = x – ai, 已知ai以后,如果能在S中找到一个数值等于x - ai,则成功.

 

    现在假设S中没有重复的数字.

    Step1. 对S进行排序. Worst case O(nlgn)时间内可以完成.

    Step2. 开辟一个辅助数组V={b1,b2,…,bn},使得bi=x – ai (1 <= i <= n). O(n)时间内搞定.

    Step3. 对V进行排序.同样O(nlgn).

      下面问题变了:在V中能不能找出一个bj,使得在S中能找出与之对应的ai,且有bj = ai?

    Step4. S和V已经排序.共2n个元素,现在开辟一个2n空间的数组E,将S与V有序的合并到E.

    Step5. 在E中去找有没有连续两个相同的元素ai,ai+1,若找到,则S中有两个元素和为x.

 

    算法的总体复杂度 = O(nlgn) + O(n) + O(nlgn) + O(n) + O(n)

                       = O(nlgn)

    所以在理论上,或在大规模的数据查找中,方法二是优于方法一的.假设有nk,使得当n>nk时,方法二优于方法一.对于方法二来讲,这个nk值会很大.

 

    方法一是蠢方法,不过大家都知道, maintainability高, robustness高;

    方法二是标准答案,在大规模数据查找的时候能显示出优势.不过既然是大规模数据处理,算法执行时又多new了2n的buffer,如果heap overflow的时候new failed,算法是准备直接返回一个”本问题算法拒绝执行”呢还是怎么办?

    本人做这个练习的时候用的是下面的方法三,robustness比2更差,不过在小规模小数据集的时候,是能比一的效率高不少.

 

我的方法三:

相比传统的方法一,主要想实现目标有两个:

一是尽量把线性查找换成别的复杂度更低的查找.这里我用了直接映射。

二是利用一些辅助空间记录一些搜索过程中已知的信息,这里我用了辅助向量。

 

假设现在有整数集合S={a1,a2,…,an}和整数x.现在假设算法所应用的范围中,可能出现的最大的整数是NMax,最小整数是NMin. 设m = NMax – NMin + 1

现在开辟一个新的数组V={b1,b2,…,bm}.这样,算法应用范围中的所有数字k都可以映射到V上去: V[ k - NMin ].

 

下面是算法:

Step1: 将V数组清0.

Step2: 对S中的每个元素ai(0<i<n+1),

      

如果V[i]为零,则V[i] = 1;

    如果V[x-i]为零,则V[i] = 1;

    否则退出,找到ai+aj=x;

Step3: 如果step2的循环能顺利执行到最后,则没有符合条件的ai和aj,使得ai+aj=x.

 

本算法可以作下面的扩展:如果要求找出S中符合条件的ai和aj,或者要求找出S中所有符合条件的ai和aj,则可以改进一下,在step2中不判断,就做两件事:

V[i] = V[i] + 1

V[x-i] = V[x-i] + 1

循环一遍后再顺序搜索一遍即可.

 

算法的时间复杂度嘛: Step1要O(n)

                    Step2要O(n)

Worst Case算法时间复杂度 = O%2

什么是CMMI:【上一篇】
lqplayer--基于gstreamer和qt的linux下的简单播放器(二):【下一篇】
【相关文章】
没有相关文章
【相关评论】
没有相关评论
【发表评论】
姓名:
邮件:
随机码*
评论*
      
|  首 页  |  版权声明  |  联系我们   |  网站地图  |
CopyRight © 2004-2007 bbb软讯网络 All Rigths Reserved.