HashMap-根据字符出现频率排序

问题描述 :

给定一个字符串,请将字符串里的字符按照出现的频率降序排列,如果频率相同,则按照字符的ASCII码升序排列。

 

示例 1:

输入:

"tree"

输出:

"eert"

解释:

'e'出现两次,'r'和't'都只出现一次。

因此'e'必须出现在'r'和't'之前,而且'r'比't'的ASCII码小。

 

示例 2:

输入:

"cccaaa"

输出:

"aaaccc"

解释:

'c'和'a'都出现三次。因此按照字符升序排列,'a'在'c'前。

 

示例 3:

输入:

"Aabb"

输出:

"bbAa"

解释:'A'和'a'被认为是两种不同的字符,并且'A'的ASCII码比'a'小

 

输入说明 :

输入一个字符串

输出说明 :

输出一个字符串,字符串中字符的顺序请参考以上说明。

输入范例 :Aabb

输出范例 :bbAa

 
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>

using namespace std;

class Solution {
public:

    string frequencySort(string s) {
         string res;

         unordered_map<char, int> counts;
         //统计每个字母的出现次数
         for(auto c : s){
            counts[c]++;
         }
         //定义一个数组存储字母以及频率为了排序
         vector<pair<char, int>> vec;
         for(auto zu : counts){
            vec.emplace_back(zu);
         }
        //按照字母出现的频率降序排序
        sort(vec.begin(), vec.end(), [](const pair<char, int> &a, const pair<char, int> &b) {
//            return a.second > b.second;
//将字符串里的字符按照出现的频率降序排列,如果频率相同,则按照字符的ASCII码升序排列
            return a.second == b.second ? a.first<b.first : a.second>b.second;
        });

        for(int i = 0; i < vec.size(); i++){
            while(vec[i].second--){
                //将 降序的字符 ch依次拼接形成字符串
                res.push_back(vec[i].first);
            }
        }

        return res;

    }
};
//时间复杂度:O(n+klogk),其中 n 是字符串 s 的长度,k 是字符串 s 包含的不同字符的个数,这道题中 s 只包含大写字母、小写字母和数字,因此 k=26+26+10=62。
//遍历字符串统计每个字符出现的频率需要 O(n) 的时间。
//将字符按照出现频率排序需要O(klogk) 的时间。
//生成排序后的字符串,需要遍历 kk 个不同字符,需要 O(k) 的时间,拼接字符串需要 O(n) 的时间。
//因此总时间复杂度是 O(n+klogk+k+n)=O(n+klogk)。
//
//空间复杂度:O(n + k),其中n 是字符串 s 的长度,k 是字符串 s 包含的不同字符的个数。空间复杂度主要取决于哈希表、列表和生成的排序后的字符串。


int main()
{
    string str;
    cin >> str;

    string res;
    res = Solution().frequencySort(str);
    cout << res << endl;

    return 0;
}

 

posted @ 2022-08-13 10:18  夏天最爱的冰淇淋  阅读(90)  评论(0)    收藏  举报