[LeetCode] Sort Characters By Frequency 根據字元出現頻率排序
阿新 • • 發佈:2018-12-27
Given a string, sort it in decreasing order based on the frequency of characters.
Example 1:
Input: "tree" Output: "eert" Explanation: 'e' appears twice while 'r' and 't' both appear once. So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer.
Example 2:
Input: "cccaaa" Output: "cccaaa" Explanation: Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer. Note that "cacaca" is incorrect, as the same characters must be together.
Example 3:
Input: "Aabb" Output: "bbAa" Explanation: "bbaA" is also a valid answer, but "Aabb" is incorrect. Note that 'A' and 'a' are treated as two different characters.
這道題讓我們給一個字串按照字元出現的頻率來排序,那麼毫無疑問肯定要先統計出每個字元出現的個數,那麼之後怎麼做呢?我們可以利用優先佇列的自動排序的特點,把個數和字元組成pair放到優先佇列裡排好序後,再取出來組成結果res即可,參見程式碼如下:
解法一:
class Solution { public: string frequencySort(string s) { string res = ""; priority_queue<pair<int, char>> q; unordered_map<char, int> m; for (char c : s) ++m[c]; for (auto a : m) q.push({a.second, a.first}); while (!q.empty()) { auto t = q.top(); q.pop(); res.append(t.first, t.second); } return res; } };
我們也可以使用STL自帶的sort來做,關鍵就在於重寫comparator,由於需要使用外部變數,記得中括號中放入&,然後我們將頻率大的返回,注意一定還要處理頻率相等的情況,要不然兩個頻率相等的字元可能穿插著出現在結果res中,這樣是不對的。參見程式碼如下:
解法二:
class Solution { public: string frequencySort(string s) { unordered_map<char, int> m; for (char c : s) ++m[c]; sort(s.begin(), s.end(), [&](char& a, char& b){ return m[a] > m[b] || (m[a] == m[b] && a < b); }); return s; } };
我們也可以不使用優先佇列,而是建立一個字串陣列,因為某個字元的出現次數不可能超過s的長度,所以我們將每個字元根據其出現次數放入陣列中的對應位置,那麼最後我們只要從後往前遍歷陣列所有位置,將不為空的位置的字串加入結果res中即可,參見程式碼如下:
解法三:
class Solution { public: string frequencySort(string s) { string res = ""; vector<string> v(s.size() + 1, ""); unordered_map<char, int> m; for (char c : s) ++m[c]; for (auto& a : m) { v[a.second].append(a.second, a.first); } for (int i = s.size(); i > 0; --i) { if (!v[i].empty()) { res.append(v[i]); } } return res; } };
類似題目:
參考資料: