Reputation: 1611
I have two list:
List<String> firstList = new LinkedList<String>();
List<String> secondList = new LinkedList<String>();
I want to know if every element of a list is contained by the other list. A possible solution could be:
public boolean function(List<String> first, List<String> second)
{
first = firstList;
second = secondList
for (String item : firstList)
{
for (String elem : secondList)
{
if(elem.compareTo(item)!=0)
return false;
}
}
return true;
}
As we can see, the time is quadratic. Is there a way to do it better?
Upvotes: 1
Views: 1322
Reputation: 726509
You have an O(n*m) implementation with O(1) space requirements; you could make an O(n+m) implementation with O(m) space requirements by adding elements of the first list to HashSet<String>
, and then verifying that all elements of the second list are present:
Set<String> firstSet = new HashSet<String>(firstList);
for (String elem : secondList) {
if(!firstSet.contains(item)) {
return false;
}
}
return true;
or even better
return new HashSet<>(firstList).containsAll(secondList);
(thanks, bradimus!)
Note: Your approach uses sub-optimal comparison mechanism: rather than calling compareTo
, you could call equals
, because you do not need to check if the word is alphabetically before or after.
Another problem is that your approach will often returns false
when it should return true
, because you return false
too early.
Upvotes: 4
Reputation: 1881
public boolean function(List<String> first, List<String> second) {
return (second.size() == first.size() && first.containsAll(second))
}
Upvotes: 1
Reputation: 872
There is an existing answer that I believe can address your question.
The idea is basically to use two Set
and to calculate the size of their intersection.
I believe that if you can afford to use Set
instead of List
so you can save time on contains
. You will have a complexity of o(n)
whatever happens.
Edit
If you care about matching duplicates in your input Lists the above solution may not be efficient. You may want to be careful about that.
Upvotes: 0
Reputation:
Try this:
!Collections.disjoint(list1, list2);
Or you can use containsAll
Hope it helps!
Upvotes: 0
Reputation: 65813
Depending on whether one or both lists change regulary you may find it more efficient to use HashSet<String>
for one that changes rarely.
See Set operations: union, intersection, difference, symmetric difference, is subset, is superset for more details.
Upvotes: 0