zoukankan      html  css  js  c++  java
  • 给定N个整数集合是否存在两个其和刚好为指定常数的元素

    又一次学习一遍<算法导论>,看到了这个问题:

    描写叙述一个执行时间为O(nlgn)的算法,使之能在给定一个由n个整数构成的集合S和还有一个整数 X 时,推断出S中是否存在有两个其和刚好等于 X 的元素。


    Solution

    (1)->对整个集合进行排序,能够用快排(含有小文件策略、三者取中策略)。时间复杂度O(nlogn)。形成一个数组A[n]。

     ->设定两个下标pBegin和pEnd,分别指向数组A[n]的头尾。pBegin = 0。pEnd = n -1。

     ->若(A[pBegin] +A[pEnd])== X,找到元素对;

     ->若A[pBegin] +A[pEnd])> X。则表示所需的元素相应该要小一些,对于已经排好序的非降序数组,仅仅须要将--pEnd就可以;

     ->A[pBegin] +A[pEnd])< X,则表示所需的元素相应该要大一些,仅仅须要将++pBegin就可以;

     ->直到 pBegin  == pEnd 。总共的时间复杂度为O(nlogn+n),空间复杂度O(1)。

    证明的思路:利用反证法。假如 (A[m] + A[k] )== X。初始化时,pBegin <= m。pEnd >= k。

    首先证明在移动过程中pBegin 不可能大于m。假如pBegin 大于m,则在ipBegin 大于m之前。必有pBegin 必会有一次等于m,当pBegin 等于m时,pEnd 是大于k的,这时的A[pBegin] + A[pEnd] > X,所以pBegin 会一直停留在m处,直到pEnd 移动到k为止。所以pBegin 不会移动超过m。

    同理能够证明pEnd 不会小于k,算法是正确。



    (2)->对于较小的X。能够考虑利用Hash的思路。直接声明一个大小为X的数组S[X],初始化所有元素为0。

    消耗X个辅助空间。

     ->遍历一次集合,对于全部小于等于X的元素k,令S[k]++。时间复杂度n;

     ->遍历数组S[X],对于不为0的元素下标m(S[m]!=0),查看S[X-m]是否为0。若m == X-m。查看S[m]>=2是否为真。

     ->总共的时间复杂度为O(X+n),空间复杂度O(X)。可是是在X较小的情况下。

     ->同一时候这种方法能够找出全部的元素对!


    拓展问题

    (1)是否存在三个元素之和正好等于给定值X? 

    【假如 A[m]+A[k]+A[s] == X。对于全部元素i,是否在集合S(除去i)中有两个元素之和等于 X-A[i]。n个元素相应n个上述的两个元素和的子问题。时间复杂度应该是O(nlogn+n^2)】不知是否有更好的思路?

    (2)给定n个整数的集合S。输出集合S中全部满足 a+b=c 的整数a、b、c。

    【类似1的解法。事实上就是 a+b-c=0的变形】



  • 相关阅读:
    Ubuntu安装Oracleclient远程连接数据库
    解决报错:Unable to process Jar entry [org/springframework/jmx/export/annotation/*****]
    解决报错:The import javax.servlet.annotation cannot be resolved
    解决导入MAVEN项目报错Dynamic Web Module 3.1 requires Java 1.7 or newer.
    python批量下载链接图片
    thrax的安装
    cmake下载与使用(含cmake安装包)
    NFA转换为DFA
    杂记
    attention机制
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5227976.html
Copyright © 2011-2022 走看看