目录
题目
给定一个字符串,请将字符串里的字符按照出现的频率降序排列。
示例 1
输入: "tree"
输出: "eert"
思路
①寻常思路
统计一下字符各自出现的频率,并依据频率进行排序
排序后的字符都存到一个动态数组中
遍历这个数组,根据每个字符出现的频率,重新组成一个字符串
class Solution {
public String frequencySort(String s) {
Map<Character, Integer> map = new HashMap<Character, Integer>();
for(int i = 0; i < s.length(); ++i){
char c = s.charAt(i);
//getOrDefault(c,0):找到key为c对应的value就返回value,否则返回0
int frequency = map.getOrDefault(c,0) + 1;
map.put(c, frequency);
}
List<Character> list = new ArrayList<Character>(map.keySet());
Collections.sort(list, (a,b) -> map.get(b) - map.get(a));
StringBuffer sb = new StringBuffer();
for(int i = 0; i < list.size(); ++i) {
char c = list.get(i);
int frequency = map.get(c);
for(int j=0;j<frequency;++j) {
sb.append(c);
}
}
return sb.toString();
}
}
其中,Collections.sort(list, (a,b) -> map.get(b) - map.get(a))用到了sort的自定义排序
map.get(b) - map.get(a)如果大于0,(a,b)位置就要互换,从而实现降序
②桶排序
1.遍历字符串,统计每个字符出现的频率,同时记录最高频率maxFreq
2.创建桶,存储从 1 到 maxFreq 的每个出现频率的字符
3.按照出现频率从大到小的顺序遍历桶,对于每个出现频率,获得对应的字符,然后将每个字符按照出现频率拼接到排序后的字符串。
所谓桶排序,如下图
class Solution {
public String frequencySort(String s) {
Map<Character, Integer> map = new HashMap<Character, Integer>();
int maxFreq = 0;
//遍历字符串,统计每个字符出现的频率,同时记录最高频率maxFreq
for(int i=0;i<s.length();++i){
char c = s.charAt(i);
int frequency = map.getOrDefault(c,0) + 1;
map.put(c,frequency);
maxFreq = Math.max(maxFreq, frequency);
}
//创建桶
StringBuffer[] buckets = new StringBuffer[maxFreq + 1];
for(int i = 0; i <= maxFreq;++i) {
buckets[i] = new StringBuffer();
}
//遍历map
for(Map.Entry<Character, Integer> entry : map.entrySet()) {
char c = entry.getKey();
int frequency = entry.getValue();
buckets[frequency].append(c);
}
//拼接字符串
StringBuffer sb = new StringBuffer();
for(int i=maxFreq;i>0;--i) {
for(int j=0;j<buckets[i].length();++j){
for(int k=0;k<i;++k){
sb.append(buckets[i].charAt(j));
}
}
}
return sb.toString();
}
}