Home > Mobile >  General question - finding possible pairs in array in less than O(N^2)
General question - finding possible pairs in array in less than O(N^2)

Time:09-16

I wander if it is possible to solve the problem in less than O(N^2). There is array a of length N and divisor k. Need to count all possible pairs (a[i], a[j]) such as i < j and a[i] a[j] can be divided by k without remainder. All I can get is two nested loops. I can create array with all remainders of a[i] divided by k, but then it is need to do similar nested loops through this array and it is O(N^2) again.

CodePudding user response:

Sort the array on a[i] mod k. This is done in time O(N Log N).

Scan the array with two indexes, left-to-right and right-to-left, in such a way that you detect the sequences of elements such that the sum mod k is 0, and multiply the lengths of these sequences. This is done in time O(N).

E.g.

2, 9, 21, 13, 1, 8, 22, 6 with k=5

After sorting,

1, 21, 6, 22, 2, 13, 8, 9

and the sequences are

||1, 21, 6|2, 22|13, 8|9|

Hence 3x1 2x2 pairs.

You need some extra trick to avoid counting the pairs i≥j. For instance, you can append to every element its initial index in the array, and sort lexicographically on the value mod k then on the index. Then when counting pairs, by a kind of merging process you can enumerate the valid pairs. The total complexity remains O(N).

CodePudding user response:

Create a bucket of remainders from 0 to k-1. Now divide every number of array with divisor k and put the number in remainder bucket based on the remainder yielded after dividing by k. Now create the pair like this -

Every number yielded remainder 1 can make pair with all numbers yielded remainder k - 1 because their sum will be perfectly divided by k (without remainder).

Similarly numbers in remainder 2 bucket will make pair with numbers in remainder k - 2 bucket. Do this for i<=j.

Also, all numbers in remainder 0 bucket will make pair among themselves.

Time complexity is O(n) and space complexity is O(k) (for bucket of remainders).

EDIT:

If just need to count the number of pairs then the remainder bucket can be like a simple array (whose all elements initialised by 0) and every element, at a particular index, will contain the number of elements of array yielded the remainder equivalent to that index. Do simple calculation - number at remainder bucket index 1 multiply by number at remainder bucket index k - 1, number at index 2 multiply by number at index k - 2 and so on (i<=j). Also, calculate the possible pairs of number at index 0. Add them all and this gives the answer.

CodePudding user response:

Write a recursive function then you will see there are oerlapping results (you are doing same calculations again). Then convet the program to a dynamic programing model which would save result for a given sub array.

  • Related