[路飞]_每天刷leetcode_65(根据字符出现频率排序)

213 阅读2分钟

「这是我参与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:

  • 1<=s.length<=51051 <= s.length <= 5 * 10^5
  • 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)

这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。