Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 2-和的线性时间算法_Algorithm - Fatal编程技术网

Algorithm 2-和的线性时间算法

Algorithm 2-和的线性时间算法,algorithm,Algorithm,给定一个整数x和一个由N个不同整数组成的排序数组a,设计一个线性时间算法来确定是否存在两个不同的索引i和j,以便a[i]+a[j]==x根据补码进行思考 在列表上迭代,找出每个项目到达X所需的数字。将数字和补码粘贴到哈希中。迭代时,检查数字或其补码是否在哈希中。如果有,请找到 编辑:还有一些时间,一些伪代码 boolean find(int[] array, int x) { HashSet<Integer> s = new HashSet<Integer>();

给定一个整数x和一个由N个不同整数组成的排序数组a,设计一个线性时间算法来确定是否存在两个不同的索引i和j,以便a[i]+a[j]==x

根据补码进行思考

在列表上迭代,找出每个项目到达X所需的数字。将数字和补码粘贴到哈希中。迭代时,检查数字或其补码是否在哈希中。如果有,请找到

编辑:还有一些时间,一些伪代码

boolean find(int[] array, int x) {
    HashSet<Integer> s = new HashSet<Integer>();

    for(int i = 0; i < array.length; i++) {
        if (s.contains(array[i]) || s.contains(x-array[i])) {
            return true;
        }
        s.add(array[i]);
        s.add(x-array[i]);
    }
    return false;
}
布尔查找(int[]数组,int x){
HashSet s=新的HashSet();
for(int i=0;i
这是一种

这是我的解决办法。我不知道是不是早就知道了。想象两个变量i和j的函数的3D图:

sum(i,j) = a[i]+a[j]
对于每个
i
都有这样的
j
a[i]+a[j]
最接近
x
。所有这些
(i,j)
对形成最接近x的线。我们只需要沿着这条线走,寻找
a[i]+a[j]==x

 int i = 0; 
 int j = lower_bound(a.begin(), a.end(), x)  -  a.begin(); 
 while (j >= 0 && j < a.size()  &&  i < a.size())  {  
    int sum = a[i]+a[j]; 
    if (sum == x)   { 
        cout << "found: " << i << " " << j << endl;  
        return;
    }
    if (sum > x)    j--;
    else            i++;
    if (i > j) break;
 }  
 cout << " not found\n";
inti=0;
int j=下限(a.begin(),a.end(),x)-a.begin();
而(j>=0&&j第一次通过搜索第一个值,即>ceil(x/2)。让我们将此值称为L
  • 从L的索引开始,向后搜索,直到找到与和匹配的另一个操作数
  • 它是2*n~O(n)

    我们可以扩展到二进制搜索

  • 使用二进制搜索搜索一个元素,这样我们就可以找到L,这样L就是min(a>ceil(x/2)中的元素)

  • 对R执行相同的操作,但现在使用L作为数组中可搜索元素的最大大小


  • 这种方法是2*log(n)。

    迭代数组并将限定的数字及其索引保存到映射中。该算法的时间复杂度为O(n)

    vector twoSum(向量和数字,整数目标){
    地图摘要;
    矢量结果;
    对于(int i=0;i
    我只想将差异添加到
    哈希集
    ,如下所示:

    public static bool Find(int[] array, int toReach)
    {
        HashSet<int> hashSet = new HashSet<int>();
    
        foreach (int current in array)
        {
            if (hashSet.Contains(current))
            {
                return true;
            }
            hashSet.Add(toReach - current);
        }
        return false;
    }
    
    publicstaticboolfind(int[]数组,int-toReach)
    {
    HashSet HashSet=新的HashSet();
    foreach(数组中的当前整数)
    {
    if(hashSet.Contains(当前))
    {
    返回true;
    }
    Add(toReach-current);
    }
    返回false;
    }
    
    注意:代码是我的,但测试文件不是。此外,哈希函数的这个想法来自网络上的各种阅读

    Scala中的一个实现。它使用hashMap和值的自定义(但很简单)映射。我同意它没有使用初始数组的排序性质

    散列函数

    我通过将每个值除以10000来确定存储桶的大小。这个数字可能会有所不同,这取决于您想要存储桶的大小,根据输入范围可以使其达到最佳

    例如,键1负责从1到9的所有整数

    对搜索范围的影响

    这意味着,对于当前值n,您希望找到补码c,例如n+c=x(x是您试图找到的2-和的元素),只有3个补码可能是:

    • -钥匙
    • -键+1
    • -键-1
    假设您的号码位于以下格式的文件中:

    0
    1
    10
    10
    -10
    10000
    -10000
    10001
    9999
    -10001
    -9999
    10000
    5000
    5000
    -5000
    -1
    1000
    2000
    -1000
    -2000
    
    下面是Scala中的实现

    import scala.collection.mutable                                                                                                                                                                       
    import scala.io.Source
    
    object TwoSumRed {
      val usage = """ 
        Usage: scala TwoSumRed.scala [filename]
      """
    
      def main(args: Array[String]) {
        val carte = createMap(args) match {
          case None => return
          case Some(m) => m
        }
    
        var t: Int = 1
    
        carte.foreach {
          case (bucket, values) => {
            var toCheck: Array[Long] = Array[Long]() 
    
            if (carte.contains(-bucket)) {
              toCheck = toCheck ++: carte(-bucket)
            }
            if (carte.contains(-bucket - 1)) {
              toCheck = toCheck ++: carte(-bucket - 1)
            }
            if (carte.contains(-bucket + 1)) {
              toCheck = toCheck ++: carte(-bucket + 1)
            }
    
            values.foreach { v =>
              toCheck.foreach { c =>
                if ((c + v) == t) {
                  println(s"$c and $v forms a 2-sum for $t")
                  return
                }
              }
            }
          }
        }
      }
    
      def createMap(args: Array[String]): Option[mutable.HashMap[Int, Array[Long]]] = {
        var carte: mutable.HashMap[Int,Array[Long]] = mutable.HashMap[Int,Array[Long]]()
    
        if (args.length == 1) {
          val filename = args.toList(0)
          val lines: List[Long] = Source.fromFile(filename).getLines().map(_.toLong).toList
          lines.foreach { l =>
            val idx: Int = math.floor(l / 10000).toInt
            if (carte.contains(idx)) {
              carte(idx) = carte(idx) :+ l
            } else {
              carte += (idx -> Array[Long](l))
            }
          }
          Some(carte)
        } else {
          println(usage)
          None
        }
      }
    }
    

    这是一个使用字典数据结构和数字补码的python版本。它具有线性运行时间(顺序为N:O(N)):

    int[]b=新的int[N];
    对于(int i=0;icout这里是O(n)时间O(1)空间的线性时间复杂度解

    public void twoSum(int[]arr){
    如果(arr.length<2)返回;
    int max=arr[0]+arr[1];
    int biger=Math.max(arr[0],arr[1]);
    int较小=数学最小值(arr[0],arr[1]);
    int-biggerIndex=0;
    int smallerIndex=0;
    对于(int i=2;i更小)
    {
    较小=arr[i];
    smallerIndex=i;
    }
    最大值=较大+较小;
    }
    }
    System.out.println(“最大和为:“+max+”,带索引[“+biggerIndex+”,“+smallerIndex+”]);
    
    }解决方案

    • 我们需要数组来存储索引
    • 检查数组是否为空或包含的元素是否少于2个
    • 定义阵列的起点和终点
    • 迭代直到满足条件
    • 检查总和是否等于目标。如果是,则获取索引
    • 如果不满足条件,则根据总和值向左或向右移动
    • 向右移动
    • 向左移动
    有关更多信息:[

    归功于列奥尼德

    如果你想试试他的java解决方案

    我删除了返回,因此如果数组已排序,但允许重复,它仍然会给出对

    static boolean cpp(int[] a, int x) {
        int i = 0;
        int j = a.length - 1;
        while (j >= 0 && j < a.length && i < a.length) {
            int sum = a[i] + a[j];
            if (sum == x) {
            System.out.printf("found %s, %s \n", i, j);
    //                return true;
            }
            if (sum > x) j--;
            else i++;
            if (i > j) break;
        }
        System.out.println("not found");
        return false;
        }
    
    静态布尔cpp(int[]a,int x){
    int i=0;
    int j=a.长度-1;
    而(j>=0&&jdef twoSum(N, x):
        dict = {}
    
        for i in range(len(N)):
            complement = x - N[i]
            if complement in dict:
                return True
            dict[N[i]] = i
    
        return False
    
    # Test
    print twoSum([2, 7, 11, 15], 9) # True
    print twoSum([2, 7, 11, 15], 3) # False
    
    int[] b = new int[N];
    for (int i = 0; i < N; i++)
    {
        b[i] = x - a[N -1 - i];
    }
    for (int i = 0, j = 0; i < N && j < N;)
        if(a[i] == b[j])
        {
           cout << "found";
           return;
         } else if(a[i] < b[j])
            i++;
         else
            j++;
    cout << "not found";
    
     public void twoSum(int[] arr){
    
       if(arr.length < 2) return;
    
       int max = arr[0] + arr[1];
       int bigger = Math.max(arr[0], arr[1]);
       int smaller = Math.min(arr[0], arr[1]);
       int biggerIndex = 0;
       int smallerIndex = 0;
    
        for(int i = 2 ; i < arr.length ; i++){
    
            if(arr[i] + bigger <= max){ continue;}
            else{
                if(arr[i] > bigger){
                    smaller = bigger;
                    bigger = arr[i];
                    biggerIndex = i;
                }else if(arr[i] > smaller)
                {
                    smaller = arr[i];
                    smallerIndex = i;
                }
                max = bigger + smaller;
            }
    
        }
    
        System.out.println("Biggest sum is: " + max + "with indices ["+biggerIndex+","+smallerIndex+"]");
    
    static boolean cpp(int[] a, int x) {
        int i = 0;
        int j = a.length - 1;
        while (j >= 0 && j < a.length && i < a.length) {
            int sum = a[i] + a[j];
            if (sum == x) {
            System.out.printf("found %s, %s \n", i, j);
    //                return true;
            }
            if (sum > x) j--;
            else i++;
            if (i > j) break;
        }
        System.out.println("not found");
        return false;
        }