问题:
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)
class Solution { //42ms
public String frequencySort(String s) {
Map<Character,Integer> map = new HashMap<>();
int max = 0;//记录最大出现次数
for (char c : s.toCharArray()){
map.put(c,map.getOrDefault(c,0) + 1);
max = Math.max(max,map.get(c));
}
List<Character>[] bucket = new ArrayList[max + 1];
int count = 0;//记录所有的字符的个数,可以减少时间
for (char c : map.keySet()){
int index = map.get(c);
if (bucket[index] == null){
bucket[index] = new ArrayList<>();
}
bucket[index].add(c);
count ++;
}
StringBuilder sb = new StringBuilder();
sb.append("");
for (int i = bucket.length - 1;i >= 0;i --){
if (bucket[i] != null){
for (char c : bucket[i]){
for (int j = 0;j < i;j ++){
sb.append(c);
}
count --;
}
if (count == 0) break;
}
}
return sb.toString();
}
}
② 堆排序实现。O(nlogn)
class Solution { //52ms
public String frequencySort(String s) {
Map<Character,Integer> map = new HashMap<>();
for (char c : s.toCharArray()){
map.put(c,map.getOrDefault(c,0) + 1);
}
PriorityQueue<Map.Entry<Character,Integer>> priorityQueue = new PriorityQueue<>(new Comparator<Map.Entry<Character, Integer>>() {
@Override
public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) {//按照出现次数降序排列
return o2.getValue() - o1.getValue();
}
});
priorityQueue.addAll(map.entrySet());
StringBuilder sb = new StringBuilder();
while(! priorityQueue.isEmpty()){
Map.Entry e = priorityQueue.poll();
for (int i = 0;i < (int)e.getValue();i ++){
sb.append(e.getKey());
}
}
return sb.toString();
}
}
③ 在discuss中看到的。
class Solution { //8ms
public String frequencySort(String s) {
int[] hash = new int[256];//用于统计出现的次数
char[] res = new char[s.length()];//记录排序后的结果
for (char c : s.toCharArray()){
hash[c] ++;
}
int i = 0;
while(i < res.length){
int max = 0;
int c = 0;
for (int j = 0;j < hash.length;j ++){
if (hash[j] > max){
max = hash[j];
c = j;
}
}
hash[c] = 0;
while(max -- > 0){
res[i ++] = (char) c;
}
}
return new String(res);
}
}