在O(n * log(n))中找到具有给定总和和乘积的一对数组元素

时间:2010-06-10 00:47:27

标签: arrays algorithm integer

设A是n个正整数的数组,k是给定的整数。

我正在寻找算法来查找数组中是否有一对元素 A[i] * A[j] == kA[i] == A[j] + k。如果有这样的一对,算法应该返回它们的索引。

这是一项家庭作业,我们被告知有一个O(n * log(n))解决方案。

5 个答案:

答案 0 :(得分:3)

Sort the array. Also build a permuted index array by initializing an auxiliary array to 0, 1, 2 ... n and swapping indices every time you swap elements in the array, Time O(nLog(n))

for each element a[i] in array, Time O(n)

  Binary Search for (a) k / a[i] or (b) a[i] - k, if found, return index j from permuted index array, Time O(log(n))

答案 1 :(得分:3)

首先是我的头脑:

Make a Map<Integer, Integer>

for each number a in A:
   if (k / a) is a key in the HashMap:
      output the index of a, and HashMap.get(k/a)
   else
      HashMap.add(a, indexof(a))

所以遍历数组是O(n),而O(log n)在Map中查找键(假设你使用了TreeMap,HashMap在最好的情况下会更好,但在最坏的情况下更糟糕)

编辑:我想这只能回答a)但你明白了

答案 2 :(得分:2)

使用nlog(n)进行排序 然后通过阵列itterate 对于每个指数,我计算A [j]需要的是为了满足方程式 检查数组中是否有这样的值

O(nlogn)+ O(N)* O(logn)
= O(nlogn)

答案 3 :(得分:2)

这有点澄清了Graphics Noob的解决方案。

此外,它更像是O(N)(假设哈希不会让我们失望),而不是O(N * log(N))。

Result findMultiplicationIndices(int[] A, int[] B, int k)
{
    HashMap<Integer,Integer> aDivisors = new HashMap<Integer,Integer>();
    for(int i=0;i<A.length;i++)
    {
        int a = A[i];
        if(a!=0)
        {
            int d = k/a;
            if(d*a == k) 
                aDivisors.put(d, i);
        }
    }
    for(int i=0;i<B.length;i++)
    {
        Integer ai = aDivisors.get(B[i]);
        if(ai != null)
            return new Result(ai, i);
    }
    return null;
}

答案 4 :(得分:0)

如果k是固定的,那么有限多个整数x,y使得x * y = k。 对于每个因子(x,y),遍历列表查找A [i] = x或A [i] = y。 总运行时间= O(n)*#因子k = O(n)(确定性地,不是关于散列的假设)

问题表明A [i]都是正的,所以k也可以用有限多种方式分解x + y = k,所以O(n)也是如此。