2

The problem is to count number of non-overlaping pairs of arrays (count all pairs of arrays such that they dont have any common elements) from given set of arrays.

For example given,

a = [1,2,3]
b = [2,3,4]
c = [6,7,8]
d = [7,10,20]

The following pairs are non-overlaping (a,c), (a,d), (b,c), (b,d) since they dont have any element in common, so the answer to this instance of problem is 4

I have an n^2 solution which computes intersection of every array with every other array, and increments the count if the intersection is empty set.

Is there an efficient way to solve this? (better than n^2)

valar morghulis
  • 141
  • 1
  • 1
  • 10
  • just need to count them, not output them. @trincot – valar morghulis Dec 15 '18 at 17:52
  • @Richard yes you are right. Updated the description – valar morghulis Dec 15 '18 at 17:58
  • 3
    What is `n`? (The effort depends on the number and the lengths of the arrays.) – Henry Dec 15 '18 at 18:12
  • I can do it in O(n) if arrays have at most one element in common, but with multiple possible intersections I don't see a way to avoid double counting without checking every pair explicitly (which is always worst case O(n^2)). –  Dec 15 '18 at 18:57
  • Perhaps we can expect a bunch of [alike questions](https://stackoverflow.com/questions/53797576/find-number-of-pairs-of-disjoint-sets-in-a-list-of-sets) – MBo Dec 16 '18 at 03:27
  • If the array is in order (as yours is), you can do it faster. You only have to move forward in your arrays when comparing. – Aldert Dec 16 '18 at 08:03

1 Answers1

3

The best I can think of is O(n * k) time and O(n + k) space, where n is the total number of elements in all the arrays and k is the total number of arrays. To the extent we can perform some checks in parallel (for example, if an arbitrary selection of array references can be reasonably expressed as a bit set, e.g., k <= 64 or small enough to combine a few of them), we could reduce the time to defacto O(n).

Simply maintain a hash map where each value seen points to a bitset of which arrays we've traversed so far included it. For each traversed array, keep a bitset representing which arrays it intersects with. For each element in the current traversed array, OR the bitset in the hash map for that value with the array's bitset-record of intersections. At the end of the transversal, the number of not-intersections is augmented by k - pop_count(array_intersection_record).

גלעד ברקן
  • 23,602
  • 3
  • 25
  • 61