14. Найти первый уникальный символ в строке
Условие задачи:
Необходимо реализовать метод findFirstUniqueLetter(String str), который возвращает первый символ строки, встречающийся ровно один раз.
Если уникальных символов нет, можно вернуть специальное значение, например пробел ' '.
Код:
public class Main {
public static void main(String[] args) {
test();
}
private static char findFirstUniqueLetter(String str) {
// Write your code here
}
private static void test() {
Map<String, Character> testInOut = new HashMap<>() {{
put("summer time sadness", 'u');
put("AA bb CC d", 'd');
}};
testInOut.forEach((input, expected) -> {
char answer = findFirstUniqueLetter(input);
if (answer == expected) {
System.out.println("Passed");
} else {
System.out.printf(
"Not passed. Received %s but expected %s%n",
answer,
expected
);
}
});
}
}
Примеры:
findFirstUniqueLetter("summer time sadness") → 'u'
findFirstUniqueLetter("AA bb CC d") → 'd'
Спойлеры к решению
Подсказки
💡 Для подсчёта удобно использовать
HashMap<Character, Integer>.💡 Затем ещё раз пройди по исходной строке слева направо.
💡 Первый символ с частотой
1 и будет ответом.Решение
private static char findFirstUniqueLetter(String str) {
Map<Character, Integer> frequencies = new HashMap<>();
for (char ch : str.toCharArray()) {
frequencies.merge(ch, 1, Integer::sum);
}
for (char ch : str.toCharArray()) {
if (frequencies.get(ch) == 1) {
return ch;
}
}
return ' ';
}
На первом проходе:
frequencies.merge(ch, 1, Integer::sum);
подсчитывается количество появлений каждого символа.
На втором проходе строка просматривается в исходном порядке:
for (char ch : str.toCharArray()) {
if (frequencies.get(ch) == 1) {
return ch;
}
}
Поэтому возвращается именно первый уникальный символ.
Для строки:
summer time sadness
первым символом, встречающимся один раз, является:
u
LinkedHashMap здесь не требуется: порядок мы получаем из второго прохода по исходной строке.
Временная сложность в среднем — O(n), дополнительная память — O(k), где k — количество различных символов.
Возврат ' ' используется как специальное значение согласно условию. В реальном коде, если пробел сам может быть уникальным символом, лучше изменить контракт метода и возвращать Optional<Character>.