Problem:
Given two Collection<?>s, check if both contain the same elements.
Solution 1:
boolean equals = c1.containsAll(c2) && c2.containsAll(c1);
Solution 2:
boolean equals = new HashSet<?>(c1).equals(new HashSet<?>(c2));
I would assume Solution 2 to be more efficient (O(n)) than Solution 1 (O(n^2)).
Am I correct or did I miss something?
The Big O complexity of these is correct, Solution 1 involves iterating over one list (O (n)) for each item in the other list, which is O (n^2).  Solution 2 involves two O (n) copies and iterating over one set (O (n)) and doing O (1) .contains() checks on the other set.  All told, that's just O (n).
But depending on your constraints you can do better (not asymptotically better, just a better implementation).
Since we're assuming no duplicate elements, there's no need to do the second .containsAll() check.  Simply check they're the same size (which might be O (n), but it's still better than duplicating an O (n^2) check) then do the .containsAll().
There's no need to convert c2 into a Set, since it will be iterated over anyways; just convert c1 and use .containsAll().
You can use instanceof Set to test if c1 or c2 is already a Set, and use that object's .containsAll() method; this will run in O (n) time even if the other object is not a set, and avoids the copying overhead that Solution 2 has.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With