--- title: '451. Sort Characters By Frequency' description: 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 icon: dot topics: - { name: "Hash Table", slug: "hash-table" } - { name: "String", slug: "string" } - { name: "Sorting", slug: "sorting" } - { name: "Heap (Priority Queue)", slug: "heap-priority-queue" } - { name: "Bucket Sort", slug: "bucket-sort" } - { name: "Counting", slug: "counting" } video: "OXdXc9HTrIg" sidebar: label: 'Sort Characters By Frequency' badge: 'Medium' --- ### 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. ## Approach ```mermaid flowchart TD S(["frequencySort(s)"]) --> F["freq: count every char of s"] F --> C["split s and sort with a two-key comparator"] C --> K1["primary: freq[b] - freq[a] — most frequent first"] C --> K2["tie-break: a.localeCompare(b) — alphabetical"] K1 --> R(["join and return"]) K2 --> R ``` ## Solution ```js /** * @param {string} s * @return {string} */ var frequencySort = function (s) { // count the frequency of each character const freq = {}; for (let c of s) freq[c] = (freq[c] || 0) + 1; // sort the characters by frequency return s .split("") .sort((a, b) => freq[b] - freq[a] || a.localeCompare(b)) .join(""); }; ```