451.Sort Characters By Frequency === ###### tags: `Medium`,`String`,`Hash Table`,`Sorting`,`Heap`,`Counting` [451. Sort Characters By Frequency](https://leetcode.com/problems/sort-characters-by-frequency/) ### 題目描述 Given a string `s`, sort it in **decreasing order** based on the **frequency** of the characters. The **frequency** of a character is the number of times it appears in the string. Return *the sorted string*. If there are multiple answers, return *any of them*. ### 範例 **Example 1:** ``` Input: s = "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: s = "cccaaa" Output: "aaaccc" Explanation: Both 'c' and 'a' appear three times, so both "cccaaa" and "aaaccc" are valid answers. Note that "cacaca" is incorrect, as the same characters must be together. ``` **Example 3:** ``` Input: s = "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. ``` **Constraints**: * 1 <= `s.length` <= 5 * 10^5^ * `s` consists of uppercase and lowercase English letters and digits. ### 解答 #### Java ```java= class Solution { public String frequencySort(String s) { // 1. Define HashMap Map<Character, Integer> map = new HashMap<>(); // 2. Set character to HashMap for(Character c : s.toCharArray()) map.put(c, map.getOrDefault(c, 0) + 1); // 3. Bucket Sort List<Character> [] bucket = new List[s.length() + 1]; for(char key : map.keySet()) { int frequency = map.get(key); if(bucket[frequency] == null) bucket[frequency] = new ArrayList<>(); bucket[frequency].add(key); } // 4. Append character to res from bucket StringBuilder res = new StringBuilder(); for(int pos = bucket.length - 1; pos >= 0; pos--) if(bucket[pos] != null) for(char c : bucket[pos]) for(int i = 0; i < pos; i++) res.append(c); return res.toString(); } } ``` > Java 寫起來的痛苦指數好高QQ > [name=Kobe] [time= Dec 3, 2022] #### Python ```python= class Solution: def frequencySort(self, s: str) -> str: Q = dict() for _s in s: if _s in Q: Q[_s] += 1 else: Q[_s] = 1 stat = [ (k,v) for k,v in Q.items()] stat = sorted(stat, key=lambda x: x[1], reverse=True) result = '' for _stat in stat: result += _stat[0]*_stat[1] return result ``` > [name=玉山] [time= Dec 3, 2022] ```python= class Solution: def frequencySort(self, s: str) -> str: counter = Counter(s) res = "" for k, v in counter.most_common(): res += (k * v) return res ``` 寫完發現上面可以濃縮成一行 ```python= class Solution: def frequencySort(self, s: str) -> str: return "".join([k * v for k, v in Counter(s).most_common()]) ``` > [name=Kobe] [time= Dec 3, 2022] #### C++ ```cpp= class Solution { public: string frequencySort(string s) { unordered_map<char, int> m; for(char c:s) { if(m.find(c) == m.end()) m[c] = 1; else m[c]++; } vector<pair<char, int>> accu; for(auto p : m) accu.push_back({p.first, p.second}); sort(accu.begin(), accu.end(), [](pair<char, int> p1, pair<char, int>p2){ return p1.second > p2.second; }); string res = ""; for(auto p : accu) res+=string(p.second, p.first); return res; } }; ``` Time: $O(n)$ Extra Space: $O(n)$ > [name=XD] [time= Dec 3, 2022] #### Javascript ```javascript= function frequencySort(s) { const map = new Map(); for (let i = 0; i < s.length; i++) { map.set(s[i], (map.get(s[i]) || 0) + 1); } const arr = Array.from(map).sort((a, b) => b[1] - a[1]); let result = ''; for (const [key, value] of arr) { result += key.repeat(value); } return result; } ``` > [name=Marsgoat] [time= Dec 3, 2022] ### Reference [回到題目列表](https://hackmd.io/@Marsgoat/leetcode_every_day)