算法初探LeetCode-根据字符出现频率排序

114 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 9 天,点击查看活动详情

LeetCode451:根据字符出现频率排序

给定一个字符串 s ,根据字符出现的 频率 对其进行 降序排序 。一个字符出现的 频率 是它出现在字符串中的次数。

返回 已排序的字符串 。如果有多个答案,返回其中任何一个。

 

示例 1:

输入: s = "tree"
输出: "eert"
解释: 'e'出现两次,'r''t'都只出现一次。
因此'e'必须出现在'r''t'之前。此外,"eetr"也是一个有效的答案。

示例 2:

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

示例 3:

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

提示:

  • 1<=s.length<=51051 <= s.length <= 5 * 10^5
  • s 由大小写英文字母和数字组成

思路分析

题目要求按字符出现的频率降序排,可以想到使用大根堆来实现降序,而统计每个字符频率使用哈希表,在堆中存放数据应包含字符以及该字符出现的次数,所以新增加一个数据类。

1.使用哈希表:key为当前字符,value为该字符出现次数。遍历整个字符串,将每个字符出现次数存入哈希表中;

2.创建一个数据类Data,包含一个char类型的字符和int类型的次数;

3.新建优先队列,即大根堆; [注]:优先队列默认以小根堆方式,此次需要修改为大根堆;

4.遍历哈希表,存入大根堆中;

5.新建StringBuilder,将大根堆中数据依次出堆,即可得到最终结果。

算法代码

//创建一个数据类Data,包含一个char类型的字符和int类型的次数
public class Data {
    public char c;
    public int count;
    public Data(char c, int count) {
        this.c = c;
        this.count = count;
    }
    public char getC() {
        return this.c;
    }
    public int getCount() {
        return this.count;
    }
}
public String frequencySort(String s) {
    Map < Character, Integer > map = new HashMap < > ();
    for (int i = 0; i < s.length(); i++) {
        char ch = s.charAt(i);
        map.put(ch, map.getOrDefault(ch, 0) + 1);
    }
    PriorityQueue < Data > heap = new PriorityQueue < Data > (new Comparator < Data > () {
        public int compare(Data d1, Data d2) {
            return d2.getCount() - d1.getCount(); //大根堆
        }
    });
    for (Map.Entry < Character, Integer > entry: map.entrySet()) {
        heap.offer(new Data(entry.getKey(), entry.getValue()));
    }
    StringBuilder sb = new StringBuilder();
    while (!heap.isEmpty()) {
        Data data = (Data) heap.poll();
        for (int i = 0; i < data.getCount(); i++) {
            sb.append(data.getC());
        }
    }
    return sb.toString();
}

结果详情

Snipaste_2023-02-12_22-43-11.png

算法复杂度

  • 空间复杂度:O(1)O(1)
  • 时间复杂度:O(n)O(n)

掘金(JUEJIN)一起进步,一起成长!