问题描述
问题:Sort Characters By Frequency
Given a string, sort it in decreasing order based on the frequency of characters.
Example 1:
Input:
"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.
Example 2:
Input:
"cccaaa"
Output:
"cccaaa"
Explanation:
Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer.
Note that "cacaca" is incorrect, as the same characters must be together.
Example 3:
Input:
"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.
问题分析
该问题是要对字符串按照其中字符出现的次数对字符进行重新排序,并将其重新打印。所以需要对字符串进行以下处理:
- 统计字符串中每个字符出现的次数;
- 按照字符串中字符的出现的次数对字符进行排序;
- 按照顺序打印字符。
直观的思路是,先利用HashMap存储字符以及相应的次数,然后采用优先队列对其进行排序存储,最后输出组成新的字符串。此方法的时间复杂度为
O
(
n
)
+
O
(
m
∗
log
m
)
O(n)+O(m*\log{m})
O(n)+O(m∗logm) ,其中
n
n
n为字符串长度,
m
m
m为不同的字符的个数。
关键问题
有了上述的思路,我们就可以进行代码实现了,此处对一些关键的代码进行分析:
-
利用
HashMap统计字符出现的次数Map<Character, Integer> map = new HashMap<>(); char[] ch = s.toCharArray(); for (char c : ch){ map.put(c, map.getOrDefault(c, 0) + 1); } -
构建
Tuple类型,同时存储字符和次数,并重写compareTo方法:class Tuple implements Comparable<Tuple>{ private final char character; private final int count; Tuple(char ch, int count){ this.character = ch; this.count = count; } @Override public int compareTo(Tuple that) { return that.count - this.count; } } -
利用优先队列对有序对进行存储排序
PriorityQueue<Tuple> queue = new PriorityQueue<>(); // HashMap 遍历 for (HashMap.Entry<Character, Integer> entry : map.entrySet()){ // 插入元素,offer() 与 add() 方法的区别在于前者在失败时返回 false,而后者抛出异常 queue.offer(new Tuple(entry.getKey(), entry.getValue())); } // 删除元素 // queue.poll(); // 头部查询 // queue.peek();


被折叠的 条评论
为什么被折叠?



