题目描述
给定一个字符串,请将字符串里的字符按照出现的频率降序排列。
样例描述
输入:
"tree"
输出:
"eert"
思路
方法一:哈希表+list+StringBuffer
HaspMap
统计每个字符出现的次数keySet
方法取出键放进一个list,对list进行降序排序,这里直接用lambda表达式
Collections.sort(list, (a, b) -> (first, second))
表示升序,后面括号中反过来就是降序- 对每一个字符出现的频次,就循环频次进行拼接到stringbuffer即可
getOrDefault(i, value)
方法。当某个键对应的值不存在时,默认设置为value
方法二:桶排序
- 由于字符出现次数会存在一个上限,即最大次数。因此可以记录这个最大值,用桶排序,记录每个字符出现的次数。每种次数对应一个桶。
- 倒序遍历所有的桶即可。 每个桶就是一个Stringbuffer,因为某个出现次数可能有不止一个字符
- 遍历map推荐用,
Map.Entry<Character, Integer> enrtry: map.entrySet()
十分高效getKey, getValue
代码
方法一:
class Solution {
public String frequencySort(String s) {
Map<Character, Integer> map = new HashMap<>();
int len = s.length();
for (int i = 0; i < len; i ++ ){
char c = s.charAt(i);
//统计每个键出现的次数
int count = map.getOrDefault(c, 0) + 1;
map.put(c, count);
}
//获取所有的键 放进一个数组
List<Character> keys = new ArrayList<>(map.keySet());
//对每个键按照值进行排序
Collections.sort(keys, (a, b) -> (map.get(b) - map.get(a)));
//遍历数组,根据字符出现次数来拼接答案
StringBuffer res = new StringBuffer();
for (int i = 0; i < keys.size(); i ++){
int counts = map.get(keys.get(i));
for (int j = 0; j < counts; j ++){
res.append(keys.get(i));
}
}
return res.toString();
}
}
方法二:
class Solution {
public String frequencySort(String s) {
Map<Character, Integer> map = new HashMap<>();
int maxCount = 0;
for (int i = 0; i < s.length(); i ++ ){
char c = s.charAt(i);
int count = map.getOrDefault(c, 0) + 1;
map.put(c, count);
//找到上限次数
maxCount = Math.max(count, maxCount);
}
//创建0~maxCount次数的桶
StringBuffer bucket[] = new StringBuffer[maxCount + 1];
for (int i = 0; i <= maxCount; i ++){
//对每一个都要new StringBuffer
bucket[i] = new StringBuffer();
}
//遍历map,将字符和出现次数进行映射。 也即使将字符装入到次数桶
for (Map.Entry<Character, Integer> entry: map.entrySet()){
char c = entry.getKey();
int count = entry.getValue();
bucket[count].append(c);
}
StringBuffer res = new StringBuffer();
//降序排序
for (int i = maxCount; i > 0; i --){
int cSize = bucket[i].length();
for (int j = 0; j < cSize; j ++){
//获取次数为i的桶的其中一个字符 每个桶装了一个Stringbuffer,可能不止一个字符次数为i
char c = bucket[i].charAt(j);
for (int k = 0; k < i; k ++){
res.append(c);
}
}
}
return res.toString();
}
}