62. Удалить повторения символов, начиная с третьего
Условие задачи:
Дан список символов List<Character>. Необходимо оставить первые два появления каждого символа, а третье и все последующие удалить.
Код:
public void removeDuplicatesFromThird(
List<Character> chars
) {
// код тут
}
Примеры:
[a, b, a, a, c, b, b] → [a, b, a, c, b]
[x, x, x, x] → [x, x]
[m, n, o] → [m, n, o]
Спойлеры к решению
Подсказки
💡 Храни количество появлений каждого символа в
💡 Для безопасного удаления во время обхода используй
💡 Удаляй элемент, если его новое количество появлений больше двух.
Map.💡 Для безопасного удаления во время обхода используй
Iterator.💡 Удаляй элемент, если его новое количество появлений больше двух.
Решение
public void removeDuplicatesFromThird(
List<Character> chars
) {
if (chars == null) {
throw new IllegalArgumentException(
"List must not be null"
);
}
Map<Character, Integer> counts = new HashMap<>();
Iterator<Character> iterator = chars.iterator();
while (iterator.hasNext()) {
Character character = iterator.next();
int count = counts.merge(
character,
1,
Integer::sum
);
if (count > 2) {
iterator.remove();
}
}
}
Iterator.remove() безопасно удаляет текущий элемент во время обхода списка и не приводит к ConcurrentModificationException.
Порядок оставшихся символов сохраняется.
Временная сложность — O(n), дополнительная память — O(k), где k — количество уникальных символов.