代码如下:

 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。

证明好困难!
   

 

最新文章

  1. jQuery中slice()用法总结
  2. iOS学习之block
  3. C#函数式编程
  4. [转]java.sql.SQLException: 无效的列索引
  5. HTML5+CSS3的响应式网页设计:自动适应屏幕宽度
  6. iOS 图片实现马赛克效果
  7. 小白日记43:kali渗透测试之Web渗透-SqlMap自动注入(一)-sqlmap参数详解TARGET
  8. ecshop里Ajax.call()方法定义
  9. 关于MVC EntityType has no key defined的问题
  10. 图标字体IcoMoon 使用
  11. vue 父组件与子组件的通信
  12. soamanager发布的Webservice服务,调用时出现http500报错
  13. VMware workstation 上克隆CentOS 6.x 系统后网卡无法启动的问题
  14. monkey事件简介
  15. Spring是如何校验XML的
  16. 最短路(bellman)-hdu2066
  17. 自定义 Git - 配置 Git
  18. 20170612xlVBA含方框文档填表
  19. web 前端遇到的问题
  20. TCP系列19—重传—9、thin stream下的重传

热门文章

  1. php取随机数 explode劫取字符串 时间定义随机数
  2. oracle的row_number()和rownum
  3. python顶级执行代码
  4. Oracle Sql优化之范围处理
  5. Windows API 之 FineFirstFile、FindNextFile
  6. 2015十大顶级开源ERP系统点评
  7. ntfs mount fail after upgrade win10
  8. Allocation Failure
  9. 转 oraenv
  10. 微信公众号系列 --- ionic在IOS的键盘弹出问题