451. 根据字符出现频率排序

451. 根据字符出现频率排序

给定一个字符串,请将字符串里的字符按照出现的频率降序排列。

示例 1:

  输入:
  "tree"

  输出:
  "eert"

解释:
'e'出现两次,'r'和't'都只出现一次。
因此'e'必须出现在'r'和't'之前。此外,"eetr"也是一个有效的答案。
示例 2:

  输入:
  "cccaaa"

  输出:
  "cccaaa"

解释:
'c'和'a'都出现三次。此外,"aaaccc"也是有效的答案。
注意"cacaca"是不正确的,因为相同的字母必须放在一起。
示例 3:

  输入:
  "Aabb"

  输出:
  "bbAa"

解释:
此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。
注意'A'和'a'被认为是两种不同的字符。

 

思路一:利用vector自定义排序

  1. 使用无序map存储字符和出现次数映射关系
  2. 在vector中存储pair对,利用vector自定义排序
#include<iostream>
#include<vector>
#include<bits/stdc++.h>
#include<map>
#include<cstring>
using namespace std;
bool cmp(const pair<char,int>& p1,const pair<char,int>& p2){
    return p1.second>p2.second;
}
class Solution{
public:

    string frequencySort(string s) {
        map<char,int>ump;
        int len=s.length();
        for (int i = 0; i < len; i++)
        {
            ++ump[s[i]];
        }
        vector<pair<char,int> > vec;
        for(map<char,int>::iterator it=ump.begin();it!=ump.end();it++){
            vec.push_back(*it);
            // cout<<it->first<<" "<<it->second<<endl;
        }
        sort(vec.begin(),vec.end(),cmp);
        len=vec.size();
        string ret;
        for (int i = 0; i < len; i++)
        {
            ret+=string(vec[i].second,vec[i].first);
        }
        return ret;
    }

};
int main(){
    Solution solution;
    string str="Aabb";
    cout<<solution.frequencySort(str);

}

 

思路二:优先队列

class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char, int> ump;
        for (const auto &c : s) {
            ++ump[c];
        }
        priority_queue<pair<int, char>> pq;
        for (const auto &m : ump) {
            pq.push({m.second, m.first});
        }        
        string ret;
        while (!pq.empty()) {
            auto t = pq.top(); 
            pq.pop();
            ret.append(t.first, t.second);
        }
        return ret;
    }
};

思路三:利用lambda自定义排序

class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char, int> ump;
        for (const auto &c : s) {
            ++ump[c];
        }
        sort(s.begin(), s.end(), [&](char &a, char &b) { return ump[a] > ump[b] || (ump[a] == ump[b] && a < b); });
        return s;
    }
};

思路四:数组下标索引

每个字符出现次数不会超过字符串s长度,将字符添加到字符出现次数对应数组下标处,然后从后向前遍历,如果对应下标不为空,则添加到结果集中。

class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char, int> ump;
        for (const auto &c : s) {
            ++ump[c];
        }
        vector<string> vec(s.size() + 1);
        string res;
        for (const auto &m : ump) {
            vec[m.second].append(m.second, m.first);
        }
        for (int i = s.size(); i > 0; --i) {
            if (!vec[i].empty()) {
                res.append(vec[i]);
            }
        }
        return res;
    }
};

 

posted @ 2020-08-20 17:35  多发Paper哈  阅读(129)  评论(0编辑  收藏  举报
Live2D