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