https://leetcode-cn.com/problems/sort-characters-by-frequency/

描述

给定一个字符串,请将字符串里的字符按照出现的频率降序排列。

样例

  1. 输入:
  2. "tree"
  3. 输出:
  4. "eert"
  5. 解释:
  6. 'e'出现两次,'r''t'都只出现一次。
  7. 因此'e'必须出现在'r''t'之前。此外,"eetr"也是一个有效的答案。
  8. 输入:
  9. "cccaaa"
  10. 输出:
  11. "cccaaa"
  12. 解释:
  13. 'c''a'都出现三次。此外,"aaaccc"也是有效的答案。
  14. 注意"cacaca"是不正确的,因为相同的字母必须放在一起。
  15. 输入:
  16. "Aabb"
  17. 输出:
  18. "bbAa"
  19. 解释:
  20. 此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。
  21. 注意'A''a'被认为是两种不同的字符。

解题思路

  • 统计每个单词出现的频率,然后按频率进行排序,然后从频率大的开始拼接字符串。O(n + klogk)。k是有多少个不同字符
  • 看了题解有桶排序的方法,因为字符出现的频率是有上限的,所以把频率当成桶,往里填字符,最后从最大的桶开始拼接字符串

    AC代码

    1. public String frequencySort(String s) {
    2. Map<Character, Integer> map = new HashMap<>();
    3. char[] chars = s.toCharArray();
    4. int max = 0;
    5. for (int i = 0; i < s.length(); i++) {
    6. int freq = map.getOrDefault(chars[i], 0) + 1;
    7. map.put(chars[i], freq);
    8. max = Math.max(max, freq);
    9. }
    10. StringBuilder[] build = new StringBuilder[max + 1];
    11. for (int i = 0; i < max + 1; i++) {
    12. build[i] = new StringBuilder();
    13. }
    14. for (Character ch : map.keySet()) {
    15. build[map.get(ch)].append(ch);
    16. }
    17. StringBuilder ans = new StringBuilder();
    18. for (int i = max; i >0 ; --i) {
    19. if (build[i].length() > 0) {
    20. for (Character ch : build[i].toString().toCharArray()) {
    21. ans.append(String.valueOf(ch).repeat(map.get(ch)));
    22. }
    23. }
    24. }
    25. return ans.toString();
    26. }