2021.05.15按照字符出现的频率排序
(题目来源:https://leetcode-cn.com/problems/sort-characters-by-frequency/ )
注意
本题较为简单,但是设计了桶排序等知识,还是做下笔记。
思路
思路1:通过频率进行排序
public String frequencySort(String s) {
if(s.length() == 0) return "";
char[] chs = s.toCharArray();
int[][] chcnt = new int[126-35+1][2];
for(int i = 0; i < chcnt.length; i++) chcnt[i][0] = i;
for(int i = 0; i < chs.length; i++) {
chcnt[chs[i]-35][1]++;
}
Arrays.sort(chcnt, new Comparator<int[]>() {
public int compare(int[] t1, int[] t2) {
return t2[1]-t1[1];
}
});
StringBuilder sb = new StringBuilder();
for(int i = 0; i < chcnt.length; i++) {
char ch = (char)(35+chcnt[i][0]);
for(int j = 0; j < chcnt[i][1]; j++) {
sb.append(ch);
}
}
return sb.toString();
}
思路2:不用排序,迭代找最大频率(性能最好)
public String frequencySort(String s) {
if(s.length() == 0) return "";
char[] chs = s.toCharArray();
int[] cnt = new int[256];
for(int i = 0; i < chs.length; i++) cnt[chs[i]]++;
StringBuilder sb = new StringBuilder();
for(int i = 0; i < chs.length; i++) {
int max = 0, maxInd = 0;
for(int j = 0; j < cnt.length; j++) {
if(max < cnt[j]) {
max = cnt[j];
maxInd = j;
}
}
cnt[maxInd] = 0; //找到最大频率后将去归零
for(int k = 0; k < max; k++) sb.append((char)maxInd);
i += max-1;
}
return sb.toString();
}
思路3:桶排序
思想:出现频率为i的放入第i个桶
public String frequencySort2(String s) {
if(s.length() == 0) return "";
Map<Character, Integer> map = new HashMap<Character, Integer>();
char[] chs = s.toCharArray();
for(int i = 0; i < chs.length; i++)
map.put(chs[i], map.getOrDefault(chs[i], 0)+1);
//定义列表数组
List<Character>[] buckets = new ArrayList[s.length()+1];
for(char k: map.keySet()) {
int v = map.get(k);
if(buckets[v] == null) buckets[v] = new ArrayList<Character>();
buckets[v].add(k);
}
int ind = 0;
for(int i = buckets.length-1; i > 0; i--) { //找到第i个桶,桶里装的是有i个重复的字符
if(buckets[i] == null) continue;
for(int j = 0; j < buckets[i].size(); j++) { // 如果里面有j个字符,一样遍历
char tmp = buckets[i].get(j);
for(int k = 0; k < i; k++) {
chs[ind++] = tmp;
}
}
}
return new String(chs);
}