55. Оставить по одному представителю каждой группы анаграмм
Условие задачи:
Дана коллекция слов. Необходимо оставить по одному слову из каждой группы анаграмм.
Слова считаются одинаковыми, если состоят из одинаковых букв без учёта регистра. В результате должен остаться первый встретившийся представитель каждой группы.
Код:
class MyCode {
public static void main(String[] args) {
List<String> anagrams = List.of(
"Race",
"NIghT",
"Angle",
"CaRe",
"angel",
"ThiNG",
"agnel",
"angel"
);
System.out.println(removeAnagrams(anagrams));
}
public static List<String> removeAnagrams(
List<String> anagrams
) {
// код тут
}
}
Ожидаемый результат:
[Race, NIghT, Angle]
Спойлеры к решению
Подсказки
💡 Для каждого слова построй канонический ключ.
💡 Приведи слово к нижнему регистру и отсортируй его символы.
💡 У всех анаграмм получится одинаковый ключ.
💡 Используй
💡 Метод
💡 Приведи слово к нижнему регистру и отсортируй его символы.
💡 У всех анаграмм получится одинаковый ключ.
💡 Используй
LinkedHashMap, чтобы сохранить порядок появления групп.💡 Метод
putIfAbsent() позволит оставить первое встретившееся слово.Решение
public static List<String> removeAnagrams(
List<String> words
) {
if (words == null || words.isEmpty()) {
return List.of();
}
Map<String, String> representatives =
new LinkedHashMap<>();
for (String word : words) {
if (word == null) {
continue;
}
String key = canonicalKey(word);
representatives.putIfAbsent(key, word);
}
return new ArrayList<>(representatives.values());
}
private static String canonicalKey(String word) {
char[] characters = word
.toLowerCase(Locale.ROOT)
.toCharArray();
Arrays.sort(characters);
return new String(characters);
}
Для слов Race и CaRe будет построен одинаковый ключ:
acer
Для слов Angle, angel и agnel ключом будет:
aegln
LinkedHashMap сохраняет порядок добавления ключей, а putIfAbsent() не заменяет первое сохранённое слово.
Временная сложность — O(n × L log L), где n — количество слов, а L — средняя длина слова. Дополнительная память — O(n × L).