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

文章目录

LeetCode第451题"根据字符出现频率排序"要求根据字符串中字符的出现频率对字符串进行排序。可以通过以下步骤解决这个问题:

方法一

  1. 使用哈希表统计每个字符的频率。
  2. 使用最大堆根据频率对字符进行排序。
  3. 根据排序结果构造输出字符串。

下面是C++实现的具体代码:

代码实现

cpp 复制代码
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <queue>
#include <utility>
using namespace std;

class Solution {
public:
    string frequencySort(string s) {
        // 1. 统计每个字符的频率
        unordered_map<char, int> frequencyMap;
        for (char c : s) {
            frequencyMap[c]++;
        }

        // 2. 使用最大堆根据频率排序字符
        priority_queue<pair<int, char>> maxHeap;
        for (auto& entry : frequencyMap) {
            maxHeap.push({entry.second, entry.first});
        }

        // 3. 根据排序结果构造输出字符串
        string result;
        while (!maxHeap.empty()) {
            auto [freq, ch] = maxHeap.top();
            maxHeap.pop();
            result.append(freq, ch);
        }

        return result;
    }
};

int main() {
    Solution solution;
    string s = "tree";
    string result = solution.frequencySort(s);
    cout << "Sorted by frequency: " << result << endl;
    return 0;
}

解释

1. 统计每个字符的频率
cpp 复制代码
unordered_map<char, int> frequencyMap;
for (char c : s) {
    frequencyMap[c]++;
}
  • 使用哈希表frequencyMap统计字符串中每个字符的出现频率。
2. 使用最大堆根据频率排序字符
cpp 复制代码
priority_queue<pair<int, char>> maxHeap;
for (auto& entry : frequencyMap) {
    maxHeap.push({entry.second, entry.first});
}
  • 使用优先队列maxHeap,其中元素是pair<int, char>,表示字符及其频率。
  • 将每个字符及其频率插入最大堆中。
3. 根据排序结果构造输出字符串
cpp 复制代码
string result;
while (!maxHeap.empty()) {
    auto [freq, ch] = maxHeap.top();
    maxHeap.pop();
    result.append(freq, ch);
}
  • 从最大堆中依次取出字符及其频率,将字符按频率重复添加到结果字符串中。

总结

这个方法的时间复杂度主要是O(N log N),其中N是字符串的长度。通过这种方式,可以高效地根据字符出现的频率对字符串进行排序。

方法二

这个实现方法主要通过哈希表统计字符频率,然后使用自定义排序规则对字符串进行排序。具体步骤如下:

  1. 使用哈希表统计每个字符的出现频率。
  2. 定义一个比较函数,根据字符的频率和字典序对字符进行排序。
  3. 使用 std::sort 函数对字符串进行排序。

下面是对这段代码的详细解释:

cpp 复制代码
#include <string>
#include <unordered_map>
#include <algorithm>
using std::unordered_map;
using std::string;
/*
 * @lc app=leetcode.cn id=451 lang=cpp
 *
 * [451] 根据字符出现频率排序
 */

// @lc code=start
class Solution {
public:
    string frequencySort(string s) {
        // 1. 使用哈希表统计每个字符的出现频率
        unordered_map<char, int> dict;  // 哈希表,键为字符,值为该字符的出现频率
        for (auto c : s) {
            dict[c]++;
        }

        // 2. 定义一个比较函数
        auto compare = [&dict](const char& a, const char& b) {
            return (dict[a] > dict[b]) || (dict[a] == dict[b] && (a < b));
        };

        // 3. 使用 std::sort 函数对字符串进行排序
        std::sort(s.begin(), s.end(), compare);

        return s;
    }
};
// @lc code=end

详细解释

  1. 统计字符频率

    cpp 复制代码
    unordered_map<char, int> dict;
    for (auto c : s) {
        dict[c]++;
    }
    • dict 是一个 unordered_map,用于存储每个字符及其出现的频率。
    • 遍历字符串 s,将每个字符的频率记录到 dict 中。
  2. 定义比较函数

    cpp 复制代码
    auto compare = [&dict](const char& a, const char& b) {
        return (dict[a] > dict[b]) || (dict[a] == dict[b] && (a < b));
    };
    • compare 是一个 lambda 表达式,用于自定义排序规则。
    • dict[a] > dict[b]:按字符频率从高到低排序。
    • dict[a] == dict[b] && (a < b):如果频率相同,则按字符的字典序从小到大排序。
  3. 排序字符串

    cpp 复制代码
    std::sort(s.begin(), s.end(), compare);
    • 使用 std::sort 函数对字符串 s 进行排序。
    • s.begin()s.end() 分别表示字符串的起始迭代器和结束迭代器。
    • compare 函数作为自定义的比较规则。

示例

假设输入字符串为 "tree"

  1. 统计字符频率:

    复制代码
    t: 1
    r: 1
    e: 2
  2. 自定义比较函数会将字符按频率从高到低排序,如果频率相同,则按字典序排序。

  3. 排序后的字符串为 "eert"

运行效果

这段代码可以正确地根据字符出现的频率对字符串进行排序,满足题目要求。你可以在你的环境中运行这个代码来验证其正确性。

相关推荐
零售ERP菜鸟1 小时前
范式革命:从“信息化”到“数字化”的本质跃迁
大数据·人工智能·职场和发展·创业创新·学习方法·业界资讯
power 雀儿2 小时前
掩码(Mask)机制 结合 多头自注意力函数
算法
会叫的恐龙2 小时前
C++ 核心知识点汇总(第六日)(字符串)
c++·算法·字符串
小糯米6012 小时前
C++顺序表和vector
开发语言·c++·算法
We་ct2 小时前
LeetCode 56. 合并区间:区间重叠问题的核心解法与代码解析
前端·算法·leetcode·typescript
Lionel6892 小时前
分步实现 Flutter 鸿蒙轮播图核心功能(搜索框 + 指示灯)
算法·图搜索算法
小妖6662 小时前
js 实现快速排序算法
数据结构·算法·排序算法
xsyaaaan2 小时前
代码随想录Day30动态规划:背包问题二维_背包问题一维_416分割等和子集
算法·动态规划
zheyutao3 小时前
字符串哈希
算法
A尘埃4 小时前
保险公司车险理赔欺诈检测(随机森林)
算法·随机森林·机器学习