Problem
LeetCode 451. Sort Characters By Frequency
1. 题目简述
给出一个字符串,将其字母按照字母出现频率进行降序排列。例如:
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.
2. 算法思路
HashTable:
一考虑到频率的问题,首先就应该想到hashmap来进行计算。然后比较麻烦的是对hashmap的value进行排序,这个需要重写一个comparator,用来排序Map.Entry,写的比较少,多练练。然后按照顺序输出就可以了。
时间复杂度为O(nlogn),这个是排序的时间复杂度;空间复杂度最大为O(n).
Bucket Sort:
第二种做法是用bucket sort,将字符放入hashmap后,计算出最大频率freq,然后简历一个长度为freq+1的list,对于不同频率的字符放入其中。
3. 解法
- HashTable
class Solution {
public String frequencySort(String s) {
Map<Character, Integer> dict = new HashMap();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
dict.put(c, dict.getOrDefault(c, 0) + 1);
}
// 重点在这里!!!Comparator的写法,以及如何对hashmap转为list后排序
List<Map.Entry<Character, Integer>> list = new ArrayList(dict.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Character, Integer>>(){
public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) {
return o2.getValue() - o1.getValue();
}
});
StringBuilder sb = new StringBuilder();
for (Map.Entry<Character, Integer> entry : list) {
int copy = entry.getValue();
char c = entry.getKey();
while (copy > 0) {
sb.append(c);
copy--;
}
}
return sb.toString();
}
}
- Bucket Sort
这里要注意三个地方:见注释。
class Solution {
public String frequencySort(String s) {
Map<Character, Integer> dict = new HashMap();
int maxFrequency = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
dict.put(c, dict.getOrDefault(c, 0) + 1);
maxFrequency = Math.max(maxFrequency, dict.get(c));
}
int size = dict.size();
// 注意1:这里定义数组时不用初始化,抽象定义
List<Character>[] bucket = new List[maxFrequency + 1];
for (Map.Entry<Character, Integer> entry : dict.entrySet()) {
// 注意2:这路记得初始化bucket数组
if (bucket[entry.getValue()] == null) {
bucket[entry.getValue()] = new ArrayList();
}
bucket[entry.getValue()].add(entry.getKey());
}
StringBuilder sb = new StringBuilder();
for (int i = maxFrequency; i > 0; i--) {
// 注意3:bucket数组可能未被初始化,这里需要判断是否为空
for (Character character : bucket[i]) {
for (int j = i; j > 0; j--) {
sb.append(character.charValue());
}
}
}
return sb.toString();
}
}