5

Let A be an array of n positive integers, and k a given integer.

I'm looking for algorithm to find if there is a pair of elements in the array such that A[i] * A[j] == k and A[i] == A[j] + k. If there is such a pair, the algorithm should return their index.

This is a homework exercise, and we're told that there is an O(n*log(n)) solution.

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
Hades200621
  • 175
  • 1
  • 10

5 Answers5

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))
bbudge
  • 1,127
  • 6
  • 7
  • You didn't say binary search! – bbudge Jun 10 '10 at 00:56
  • Darn, I took for granted a sorted list would be binary searched. w/e points for both of us :) And I'm sure we'll get an A, but now the question is googlable for his classmates so the curve will get him! – Jean-Bernard Pellerin Jun 10 '10 at 01:01
  • @bbudge: I will tell you how. Most experienced SO users realize that doing someone's homework for him is counterproductive and prefer to offer guidance without giving the solution away so that the poster can learn on his own. – danben Jun 10 '10 at 01:11
  • @danben: there are still many that will use questions on SO to brush up their own skills and will solve anything they find interesting time permitting. – Unreason Jun 10 '10 at 12:37
3

First thing off the top of my head:

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))

So it's O(n) to traverse the array, and O(log n) to look up the key in the Map (assuming you used a TreeMap, a HashMap could be better in the best case but worse in the worst case)

Edit: I guess that only answers a) but you get the idea

Graphics Noob
  • 9,790
  • 11
  • 46
  • 44
  • Jean-Bernard Pellerin was first so accepted his answer as well as Graphics Noob (not so noob after all :?) for the more effect running time thanks alot people this forum is realy great... – Hades200621 Jun 10 '10 at 01:30
2

use nlog(n) to sort
then itterate through the array
for each index i calculate what A[j] would need to be in order for the equation to be satisfied
check to see if theres such a value in the array

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

Jean-Bernard Pellerin
  • 12,556
  • 10
  • 57
  • 79
2

Here is somewhat clarified Graphics Noob's solution.

Also, it is more like O(N) (assuming hashing won't fail us), not 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;
}
Rotsor
  • 13,655
  • 6
  • 43
  • 57
  • Rotsor thanks for you effort... wondering why no one haven't suggested to use heap :) – Hades200621 Jun 10 '10 at 01:48
  • @gleb-pendler Maybe because heap is basically the same thing as sorted array in our case? Heap is good for adding items on the fly, otherwise it just sorts. – Rotsor Jun 10 '10 at 01:58
  • It should now. Ugly though, needed 9 lines of code to handle such a simple case (k==0) O_O – Rotsor Jun 10 '10 at 02:13
  • One more thing to note: the maximum number of elements in the map equals to the [number of divisors](http://en.wikipedia.org/wiki/Divisor_function) for K, which is O(k^log(2)^(1/log(log(k))) memory and equals to 1600 for 31-bit integers. :) – Rotsor Jun 10 '10 at 03:57
  • The asymptotic formula for an average number of divisors turned out to be simpler - it is just log(K). – Rotsor Jun 10 '10 at 04:17
0

If k is fixed, then there are finitely many integers x, y such that x*y = k. For each factor (x,y), iterate through the list finding whether A[i] = x or A[i] = y. Total run time = O(n) * # factors of k = O(n) (deterministically, not assumptions about hashing)

The problem states that A[i] are all positive, so k can be decomposed x + y = k in finitely many ways as well, so O(n) as well.