《算法导论》习题2.3-7 查找集合S中是否有两个元素和为X---Java实现
代码如下:
public class MergeSort {
public static void sort(int [] A,int p, int r)
{
if(p<r)
{
int q = (int) Math.floor( (p+r)/2 );
sort(A,p,q);
sort(A,q+1,r);
merge(A,p,q,r);
}
return ;
}
public static void merge(int [] A, int p, int q, int r)
{
int n1 = q-p+1;
int n2 = r-q;
int [] L = new int[n1];
int [] R = new int[n2];
for(int i=0; i<n1; i++)
L[i] = A[p+i];
for(int i=0; i<n2;i++)
R[i]=A[q+i+1];
int i=0;
int j=0;
int counter = p;
while(i<L.length && j<R.length)
{
if(L[i]<=R[j])
{
A[counter]=L[i];
i++;
}
else
{
A[counter]=R[j];
j++;
}
counter++;
}
if(i==L.length)
{
for(int k=j;k<R.length;k++)
A[counter++] = R[k];
}
else
{
for(int k=i;k<L.length;k++)
A[counter++] = L[k];
}
}
}
public class SumTwoEqual {
/**
* @param args
*/
public static boolean TestExists(int A[],int X)
{
MergeSort.sort(A, 0, A.length - 1 );
int i = 0;
int j = A.length-1;
while(i<j)
{
if(A[i]+A[j]==X)
return true;
else if(A[i]+A[j] > X)
j--;
else
i++;
}
return false;
}
public static void main(String[] args) {
int A[] = {1,2,5,7,9,14,25,35,13,15};
boolean a = TestExists(A,22);
System.out.println(a);
}
}
算法思想很简单,就是先排序,然后从两边往中间找。除了上述的解法,还有一种方法是先排序,然后遍历所有元素a,二分查找X-a。虽然写出了上述的算法,但是说明算法的正确性是个很难的问题。下面我给出一个大致的思路,但是不是很严谨。 我们首先假设所有的元素已经从小到大排序好了,放在数组A[1...n]中,要查询的元素是X。1、如果A中没有任何两个元素的和是X,那么程序一定会返回false,这是很显然的。2、所以,问题的关键在于证明:如果A中有两个元素a,b,使得a+b==X(不妨设a<=b),那么程序会保证返回true。3、而为了证明2,则只需要证明:每一轮迭代开始之前,A[i...j]中一定包含a和b,而A[0...i-1] υ A[j+1...n]一定不包含a和b。为什么证明了3,就能证明2呢?那是因为每一次迭代A[i...j]长度都会减一(要么i+1,要么j-1),而只要a和b还在A[i...j]中,最终一定会在某一次迭代中发现A[i]==a,A[j]==b,从而程序返回true。最坏的情况是,迭代一直进行到i+1==j的时候,此时A[i]一定是a,A[j]一定是b。 下面归纳地证明3,即证明:每一轮迭代开始之前,A[i...j]中都包含a和b,而A[0...i-1] υ A[j+1...n]都不包含a和b。令ik,jk表示第k轮迭代开始之前,i和j的取值。1、第 1 轮迭代开始之前,A[i1...j1]也就是A[0...n],a和b当然包含在其中,A[0...-1] υ A[n+1...n]是空集,当然不包含a和b。结论成立。2、假设第 K 轮迭代开始之前,A[ik...jk]中包含a和b,而A[0...ik-1] υ A[jk+1...n]不包含a和b。 那么如果A[ik]+A[jk]==X,那么程序就返回true了。第 K+1 轮迭代不会发生。结论成立。 如果A[ik]+A[jk]>X,按照程序,jk会减1,那么第K+1轮开始之前,ik+1==ik,jk+1==jk-1。下面用反证法证明A[jk]不可能是b(A[jk]当然不可能是a)。因为如果A[jk]是b,那么 X<A[ik]+b<A[ik+1]+b<A[ik+2]+b<...<A[jk-1]+b,那么a就不可能是A[ik...jk-1]中的任何一个元素,这和初始假设A[i...j]中包含a和b矛盾。所以A[jk]不可能是b。所以a和b仍然包含在A[ik+1...jk+1]中。 如果A[i]+A[j]<X,那么A[i]不可能是a(因为b>=a,所以A[i]当然不可能是b)。因为如果A[i]是a,那么 a+A[i+1]<a+A[i+1]<a+A[i+2]<...<a+A[j]<X,那么b就不可能是A[i+1...j]中的任何一个元素,这和初始假设A[i...j]中包含a和b矛盾。 所以,如果A[i]+A[j]>X,按照程序,j会减1,也就是在在第K+1轮迭代开始之前,数据是A[i...j-1],因为A[j]不可能是b,所以A[i...j-1]中仍然包含a和b 如果A[i]+A[j]<X,i会加1,也就是在第K+1轮迭代开始之前,数据是A[i+1...j],因为A[i]不可能是a,所以A[i+1...j]仍然包含a和b。3、由1和2可知,在每一轮迭代开始之前,A[i...j]中一定包含a和b,而A[0...i-1] υ A[j+1,n]一定不包含a和b。 证明好困难!
《算法导论》习题2.3-7 查找集合S中是否有两个元素和为X---Java实现的更多相关文章
- 算法导论----VLSI芯片测试; n个手机中过半是好的,找出哪些是好手机
对于分治(Divide and Conquer)的题目,最重要是 1.如何将原问题分解为若干个子问题, 2.子问题中是所有的都需要求解,还是选择一部分子问题即可. 还有一点其实非常关键,但是往往会被忽 ...
- 《算法导论》2.3-7 检查集合中是否存在两数字和为指定的X--算法和证明
习题2.3-7:设计一个算法,对于一个给定的包含n个整数的集合S和另一个给定的整数X,该算法可以在时间内确定S中是否存在两个元素,使得它们的和恰为X. 解题思路:首先应该想到的是先用一个的排序算法对S ...
- 算法导论课后习题解答 第一部分 练习1.1-1->1.1-5
很高兴能和大家一起共同学习算法导论这本书.笔者将在业余时间把算法导论后面的题解以博文的形式展现出来希望能得到大家的支持谢谢.如果有可能我会做一些教学视频免费的供大家观看. 练习题选自算法导论中文第三版 ...
- 【算法导论-36】并查集(Disjoint Set)具体解释
WiKi Disjoint是"不相交"的意思.Disjoint Set高效地支持集合的合并(Union)和集合内元素的查找(Find)两种操作,所以Disjoint Set中文翻译 ...
- 为什么你学不会递归?告别递归,谈谈我的一些经验 关于集合中一些常考的知识点总结 .net辗转java系列(一)视野 彻底理解cookie,session,token
为什么你学不会递归?告别递归,谈谈我的一些经验 可能很多人在大一的时候,就已经接触了递归了,不过,我敢保证很多人初学者刚开始接触递归的时候,是一脸懵逼的,我当初也是,给我的感觉就是,递归太神奇了! ...
- 算法导论(第三版)Exercises2.3(归并排序、二分查找、计算集合中是否有和为X的2个元素)
2.3-1: 3 9 26 38 41 49 52 59 3 26 41 52 9 38 49 57 3 41 52 26 38 57 9 49 3 41 52 26 38 ...
- [置顶] 《算法导论》习题解答搬运&&学习笔记 索引目录
开始学习<算法导论>了,虽然是本大部头,可能很难一下子看完,我还是会慢慢地研究的. 课后的习题和思考有些是很有挑战性的题目,我等蒻菜很难独立解决. 然后发现了Google上有挺全的algo ...
- (搬运)《算法导论》习题解答 Chapter 22.1-1(入度和出度)
(搬运)<算法导论>习题解答 Chapter 22.1-1(入度和出度) 思路:遍历邻接列表即可; 伪代码: for u 属于 Vertex for v属于 Adj[u] outdegre ...
- 算法导论-散列表(Hash Table)-大量数据快速查找算法
目录 引言 直接寻址 散列寻址 散列函数 除法散列 乘法散列 全域散列 完全散列 碰撞处理方法 链表法 开放寻址法 线性探查 二次探查 双重散列 随机散列 再散列问题 完整源码(C++) 参考资料 内 ...
随机推荐
- pipe的实现
本文进行了详细的描述,http://blog.csdn.net/zhouhong1026/article/details/8151235
- HDU1492/The number of divisors(约数) about Humble Numbers
题目连接 The number of divisors(约数) about Humble Numbers Time Limit: 2000/1000 MS (Java/Others) Memory L ...
- NSObject Class 浅析
Objective-C中有两个NSObject,一个是NSObject类,另一个是NSObject协议.而其中NSObject类采用了NSObject协议.在本文中,我们主要整理一下NSObject类 ...
- 转:Jmeter--google plugin插件监控被测系统资源方法
一.插件准备 1.插件下载地址 http://jmeter-plugins.org/downloads/all/ 以下有两个版本的,1.1.2和1.1.3,注意Jmeter版本 1.1.2支持Jmet ...
- 吾爱破解脱壳练习第五期------upx壳
内存镜像法: 载入OD:
- Javascript模块化编程:AMD规范及require.js用法【转】 - loheonly的笔记 - 前端网(W3Cfuns)
http://www.w3cfuns.com/blog-5425789-5399326.html
- 为什么有时候必须添加sys.setdefaultencoding('utf-8')
今天在尝试Python的CGI模块时遇到中文字符不能正确显示的问题,很郁闷.在网上仔细找了找,终于解决了这个问题,现在将解决方法陈述如下,以防下次失误. 页面源代码如下 #-*- coding: ut ...
- 고 해서: 表示在做B的各种理由中, A是代表性的理由
1. 날씨도 좋고해서 산책이나 하려고 해요. 2. 할 일도 없고해서 일찍 돌어왔어요. 3. 기분도 우울하고 해서 친구란 술 마시기로 했어요. 可以加过去式和将来时使用 1. 수업도 끝 ...
- Excel相关问题
Excel默认永远使用最后安装的那个Excel版本打开.但是如果有一个Excel已经启动了,则使用那个Excel打开. 1.打开“开发工具”选项卡2007中:[Excel选项]-[常用]2010中:[ ...
- Abandoned country
Abandoned country Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...