LeetCode 451. Sort Characters By Frequency
2020-05-22 20:39:54 # leetcode

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. 解法

  1. HashTable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

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();
}
}
  1. Bucket Sort

这里要注意三个地方:见注释。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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();
}
}