「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战」
根据字符出现频率排序 Sort Characters by Frequency
LeetCode传送门451. 根据字符出现频率排序
题目
给定一个字符串,请将字符串里的字符按照出现的频率降序排列。
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:
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.
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.
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:
- s consists of uppercase and lowercase English letters and digits.
思考线
解题思路
这个题目的解题思路并不难,总结下来可以分为以下两步
- 把字符串中的字母统计频率
- 把统计频率后的字母按照从高到底的顺序排列,并构建出对应的目标字符串
有了思路之后我们就可以愉快的来写代码了。
首先我们创建一个hash
对象来存我们字符频率,key
为字符串,value
为频率。这样遍历一遍字符串后我们就完成了 统计字母频率的工作。
接下来我们要做的是把hash
对象中的字符按照频率来排序。我们可以用到Object.entries
方法来获取到[key, value]
数组,这样的话我们再调用sort
方法就可以得到对应的频率由大到小的数组。
完成的了上面的工作,接下来只剩下一项工作了,那就是把这个频率由大到小的数组组合成一个字符串,我们很容易的就想到了reduce
方法来完成。
根据上面的思路,我写出了以下代码:
function frequencySort(s: string): string {
const hash: { string?: number } = {}
const len = s.length;
for (let i = 0; i < len; i++) {
if (!hash[s[i]]) {
hash[s[i]] = 1;
} else {
hash[s[i]]++;
}
}
const ob = Object.entries(hash).sort((a, b) => b[1] - a[1]).reduce((a,b)=>{
return a + b[0].repeat(b[1])
} , '');
return ob
};
时间复杂度
O(N + KlogK): N 为字符串的长度,K为字符串中字母的个数(字符串频率数组排序的时间复杂度为KlogK)
这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。