Самый простой способ проверить, если список содержит какие-либо элементы из другого списка, чтобы позвонить contains()
на одном из списков, передавая каждый элемент в качестве аргумента в очередь. Что-то вроде:
public <E> boolean slowListContains(List<E> a, List<E> b) {
for (E element : a) {
if (b.contains(element)) {
return true;
}
}
return false;
}
Это медленно, однако, поскольку является линейной операцией (O(n)
), и так как мы называем его в цикле функция slowListContains()
занимает квадратичное время (O(n^2)
), который беден. Мы можем сделать лучше.
Set
(или более точно на основе хэш-набор, такие как HashSet
) имеет эффективную метода, который работает в менее чем линейное время (постоянное время в случае HashSet
). Преобразование одного или другого списка в Set
сделает цикл в slowListContains()
намного быстрее. Что-то вроде:
public <E> boolean fasterListContains(List<E> a, List<E> b) {
Set<E> aSet = new HashSet<>();
aSet.addAll(a);
for (E element : b) {
if (aSet.contains(b)) {
return true;
}
}
return false;
}
Это не идеально, но это, безусловно, намного быстрее, чем наивное решение. Небольшое улучшение будет заключаться в том, чтобы всегда преобразовывать меньший список в Set
, а не в первый. Вы также можете взять произвольные параметры Iterable
, а не List
, а затем проверить, является ли любой из них уже Set
, и если это так, пропустите шаг установки-построения.
Действительно оцените ваши усилия для объяснения Sir :) –