Во время собеседования на должность разработчика Java меня спросили следующее:
Напишите функцию, которая принимает два параметра:
- Строка, представляющая текстовый документ и
- целое число, представляющее количество возвращаемых предметов.
Реализуйте функцию так, чтобы она возвращала список Строк, упорядоченных по частоте слова, первое из которых встречается чаще всего. Ваше решение должно выполняться за время где - количество символов в документе.
Вот что я ответил (в псевдокоде), это не а скорее время из-за сортировки. Я не могу понять, как это сделать раз.
wordFrequencyMap = new HashMap<String, Integer>();
words = inputString.split(' ');
for (String word : words) {
count = wordFrequencyMap.get(word);
count = (count == null) ? 1 : ++count;
wordFrequencyMap.put(word, count);
}
return wordFrequencyMap.sortByValue.keys
Кто-то знает, или кто-то может дать мне несколько советов?
algorithms
sorting
strings
data-mining
user2712937
источник
источник
Hashtable
является ли устаревшая Java или нет действительно неуместной для целей этого сайта.Ответы:
Я предлагаю вариант подсчета распределения:
maxWordCound
. -maxWordCount
. Тип записи - это списки строк. - , так как количество не может быть выше.Возможно, вы можете заменить три других структур данных на первом этапе.
источник
Собрание количества вхождений равно O (n), поэтому хитрость заключается только в том, чтобы найти только верхние значения k вхождений.
Куча - это распространенный способ агрегирования верхних значений k, хотя могут использоваться и другие методы (см. Https://en.wikipedia.org/wiki/Partial_sorting ).
Предполагая, что k является вторым параметром выше, и что это константа в постановке задачи (она выглядит так):
Поскольку размер кучи является постоянным, операции кучи - это O (1), поэтому шаг 3 - это O (n).
Куча также может поддерживаться динамически при построении дерева.
источник
Ваш алгоритм даже не запускается за время ; вставка Θ ( n ) вещей в хеш-таблицу уже стоит время Ω ( n 2 ) (наихудший случай).O ( n logн ) Θ ( н ) Ω ( n2)
То, что следует, неправильно ; Я оставляю это здесь пока в иллюстративных целях.
Следующий алгоритм выполняется в наихудшее время (при условии алфавита Σ постоянного размера), n количество символов в тексте.O(n) Σ n
Построить дерево суффиксов текста, например, с помощью алгоритма Укконена .
Если конструкция еще не делает этого, добавьте число достижимых листьев для каждого (внутреннего) узла.
Пройдите по дереву от корня и отрежьте все ветви в первом (белом) пространстве.
Пройдите по дереву и отсортируйте список дочерних элементов каждого узла по количеству листьев.
Выход дерева (листья слева направо) теперь представляет собой список всех слов, отсортированных по частоте.
Что касается времени выполнения:
Более точные границы могут быть получены путем параметризации времени выполнения с количеством разных слов; если их мало, дерево мало после 2.
источник
Используйте хеш-таблицу (например,1..n O(n) O(n)
HashMap
), чтобы собрать все слова и их частоты. Затем используйте сортировку подсчета, чтобы отсортировать слова в порядке убывания частоты. Поскольку все частоты являются целыми числами в диапазоне , сортировка при подсчете занимает время O ( n ) . Общее ожидаемое время работы O ( n ) , что более чем вероятно более чем достаточно для всех практических целей (если интервьюер не упомянул что-то, что было оставлено вне вашего вопроса). Не забудьте упомянуть, что это ожидаемое время выполнения, а не время выполнения в худшем случае .Это может не быть ответом, который учитель будет искать в классе алгоритмов, потому что это ожидаемое время выполнения а не время выполнения O ( n ) в худшем случае. Если вы хотите набрать дополнительные баллы на вопросе об интервью, вы можете небрежно упомянуть, что, конечно, это ожидаемое время выполнения, но это также можно сделать за O ( n ) наихудшее время выполнения, заменив хэш-таблица с более сложной структурой данных - и вы были бы рады подробно рассказать о том, как вы будете выбирать между алгоритмами в такой ситуации.O(n) O(n) O(n)
источник
Решение на основе хэш-таблицы
Предполагается, что алгоритм хеширования является линейным по времени относительно количества символов.
Решение на основе сортировки Radix
В качестве альтернативы, если исходить из английского, поскольку длина слов хорошо известна, я бы вместо этого создал сетку и применил бы сортировку по основанию, котораяO(kN) k N n k O(n)
Первые несколько самых длинных слов в английском языке смехотворно длинные , но тогда можно ограничить длину слова разумным числом (например, 30 или меньше) и обрезать слова, принимая допущенную погрешность.
источник