Sort Characters By Frequency
Given a string s, sort it in decreasing order based on the frequency of each character, and return the resulting string. Tally every character into a bucket keyed by how often it occurs, then read the buckets back from the highest count down to the lowest, writing each character out its full count at a time.
Constraints
- 1 ≤ s.length ≤ 5 × 105
- s consists of uppercase and lowercase letters and digits
Example
s = "tree""eetr"Explanation 'e' appears twice and must come before any single-occurrence character, giving "eetr" (any ordering of the count-1 characters is valid).
In plain terms
- Frequency
- How many times a particular character occurs in the string.
Count each character, then write out the buckets by count, highest first
s="tree". Count how often each character appears.
What happens in this step
s = "tree" (indices 0-3: t, r, e, e)
counts = {} (empty map, about to tally each character)Steps to visualize
- Count how many times each character occurs in s.
- Group characters into buckets keyed by their count.
- Walk the buckets from the highest count down to the lowest.
- For each bucket, write every character in it out that many times.
Walk through the code
Same walkthrough, now with the code. Press Next to move one step and watch which lines run.
s="tree". Count how often each character appears.
What happens in this step
s = "tree" (indices 0-3: t, r, e, e)
counts = {} (empty map, about to tally each character)Solution
function frequencySort(s) {
const counts = new Map();
for (const ch of s) {
counts.set(ch, (counts.get(ch) || 0) + 1);
}
const buckets = new Array(s.length + 1).fill(null).map(() => []);
for (const [ch, count] of counts) {
buckets[count].push(ch);
}
let result = '';
for (let count = buckets.length - 1; count >= 1; count--) {
for (const ch of buckets[count]) {
result += ch.repeat(count);
}
}
return result;
}- Time
- O(n + k)
- Space
- O(n)
Test cases
| Input | Expected | Covers |
|---|---|---|
s = "tree" | "eetr" | example from the docstring |
s = "cccaaa" | "cccaaa" | two characters tied for the highest frequency |
s = "Aabb" | "bbAa" | uppercase and lowercase letters treated as distinct characters |
s = "a" | "a" | smallest valid input, a single character |
s = "abc" | "abc" | every character occurs exactly once |
s = "2211" | "2211" | digit characters, already grouped by value |
s = "aabbbcccc" | "ccccbbbaa" | three characters with three distinct frequency counts |