hashmap+bucket sort O(n+k) worst case O(nlogn) 跟347. Top K Frequent Elements 思路基本一样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution {public : vector <string > topKFrequent (vector <string >& words, int k) { unordered_map <string , int > m; for (const auto &w : words) { ++m[w]; } int n = words.size(); vector <set <string >> buckets(n + 1 ); for (auto [w, freq] : m) { buckets[freq].insert(w); } vector <string > res; for (int i = n; i >= 0 ; --i) { for (const auto &w : buckets[i]) { res.push_back(w); if (size(res) == k) return res; } } return res; } };
hashmap+trie+bucket sort O(n+k*w) time O(n) space w是平均字符长度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 class Solution {public : vector <string > topKFrequent (vector <string >& words, int k) { unordered_map <string , int > m; for (const auto &w : words) { ++m[w]; } int n = words.size(); vector <TrieNode *> buckets (n + 1 , nullptr ) ; for (auto && b : buckets) { b = new TrieNode; } for (const auto &p : m) { insert(buckets[p.second], p.first); } vector <string > res; for (int i = n; i >= 0 && k > 0 ; --i) { getWords(buckets[i], k, res); } return res; } struct TrieNode { TrieNode *children[26 ] = {nullptr }; bool isEnd = false ; string w; }; void insert (TrieNode *p, const string &w) { for (char c : w) { if (!p->children[c - 'a' ]) { p->children[c - 'a' ] = new TrieNode; } p = p->children[c - 'a' ]; } p->isEnd = true ; p->w = w; } void getWords (TrieNode *p, int &k, vector <string > &res) { if (!p || k == 0 ) return ; if (p->isEnd) { res.push_back(p->w); --k; } for (int i = 0 ; i < 26 ; ++i) { getWords(p->children[i], k, res); } } };
quickselect O(n+klogk) time worst case O(nlogn) O(n) space
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution {public : vector <string > topKFrequent (vector <string >& words, int k) { unordered_map <string , int > m; for (const auto &w : words) { ++m[w]; } vector <pair <string , int >> v(begin(m), end(m)); auto cmp = [](const auto &a, const auto &b){ return a.second == b.second ? a.first < b.first : a.second > b.second; }; nth_element(begin(v), begin(v) + k, end(v), cmp); sort(begin(v), begin(v) + k, cmp); vector <string > res; for (const auto &[w, f] : v) { res.push_back(w); if (size(res) == k) return res; } return res; } };