Вы всегда будете использовать хэш для подсчета слов первого, который будет использования конечно O (п) и O (п) пространство. Это первый шаг.
Тогда вы узнаете, как выбрать верхнюю часть 10. Вы можете использовать сортировку, которая занимает не менее O (nlogn). Но есть лучший способ, который заключается в использовании кучи. Скажем, k = 10 в вашем случае. Вам нужно добавить парный объект слова и его частоту в минимальную кучу размера k, где мы используем частоту в качестве ключа для мини-кучи. Если куча заполнена, удалите минимальный элемент (верхний) из кучи и добавьте новую пару слов-слов только в том случае, если частота этого слова имеет частоту, большую, чем верхнее слово в куче. После того, как мы сканировали все слова на карте, и куча была должным образом обновлена, элементы, содержащиеся в мини-куче, являются самыми большими. Ниже приведен пример кода. Просто немного измените код, чтобы взять ArrayList, а не массив, который сделает вашу работу.
class Pair {
String key;
int value;
Pair(String key, int value) {
this.key = key;
this.value = value;
}
}
public class Solution {
/**
* @param words an array of string
* @param k an integer
* @return an array of string
*/
private Comparator<Pair> pairComparator = new Comparator<Pair>() {
public int compare(Pair left, Pair right) {
if (left.value != right.value) {
return left.value - right.value;
}
return right.key.compareTo(left.key);
}
};
public String[] topKFrequentWords(String[] words, int k) {
if (k == 0) {
return new String[0];
}
HashMap<String, Integer> counter = new HashMap<>();
for (String word : words) {
if (counter.containsKey(word)) {
counter.put(word, counter.get(word) + 1);
} else {
counter.put(word, 1);
}
}
PriorityQueue<Pair> Q = new PriorityQueue<Pair>(k, pairComparator);
for (String word : counter.keySet()) {
Pair peak = Q.peek();
Pair newPair = new Pair(word, counter.get(word));
if (Q.size() < k) {
Q.add(newPair);
} else if (pairComparator.compare(newPair, peak) > 0) {
Q.poll();
Q.add(new Pair(word, counter.get(word)));
}
}
String[] result = new String[k];
int index = 0;
while (!Q.isEmpty()) {
result[index++] = Q.poll().key;
}
// reverse
for (int i = 0; i < index/2; i++) {
String temp = result[i];
result[i] = result[index - i - 1];
result[index - i - 1] = temp;
}
return result;
}
}
upvote для 'Collectors.groupingBy()', я полностью забыл об этой приятной функции. – hoefling
Вот как это сделать. Яркий и элегантный. – duffymo
@FedericoPeraltaSchaffner черт возьми, вы хорошо разбираетесь в Java! – Iona