451.根据字符出现频率排序(中等)

LeetCode 451.根据字符出现频率排序题目链接

题目描述:

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

示例 1:

输入:“tree”
输出:“eert”
解释:'e’出现两次,'r’和’t’都只出现一次。因此’e’必须出现在’r’和’t’之前。此外,"eetr"也是一个有效的答案。

示例 2:

输入:“cccaaa”
输出:“cccaaa”
解释:'c’和’a’都出现三次。此外,"aaaccc"也是有效的答案。
注意"cacaca"是不正确的,因为相同的字母必须放在一起。

示例 3:

输入:“Aabb”
输出:“bbAa”
解释:此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。注意’A’和’a’被认为是两种不同的字符。

题目分析:

用桶排序求解,跟LeetCode 347.前K个高频元素思路基本一致,差别在于需要把在list重复元素按重复次数取出来。首先创建字典集map,统计数组中的每个字符出现的次数,字符为键,出现的次数为值。然后创建list集合,遍历map,按照字符出现的次数作为下标,把键值放入list集合中。list集合为频次集合。最后创建返回的结果集,从大到小遍历list频次集,按频次取出元素返回即可。

题解(桶排序解法):

执行用时: 11 ms
内存消耗: 39.6 MB

class Solution {
    public String frequencySort(String s) {
        // 先把字符串转换为字符数组,便于我们操作
        char[] charArray = s.toCharArray();
        // 创建结果集
        char[] result = new char[s.length()];
        // 使用字典,统计每个字符出现的次数,字符为键,元素出现的次数为值
        HashMap<Character,Integer> map = new HashMap<>();
        // 遍历数组
        for (char c : charArray)
            // 统计元素出现次数
            map.put(c,map.getOrDefault(c,0) + 1);
        // 创建list集合
        List<Character>[] list = new List[charArray.length+1];
        // 遍历map集合键集
        for (Character c : map.keySet()) {
            // 如果list为空,则新建ArrayList
            if (list[map.get(c)] == null)
                list[map.get(c)] = new ArrayList<>();
            // 获取键值出现的次数作为下标,把键放入list中
            list[map.get(c)].add(c);
        }
        // 定义索引
        int index = 0;
        // 从大到小遍历list频次数组集合
        for (int j = list.length - 1; j > 0; j--) {
            // 如果当前不为空
            if (list[j] != null)
                // 遍历当前list里面的元素
                for (Character c : list[j]) {
                    // 把元素放入结果集
                    for (int k = 0; k < j; k++) {
                        result[index] = c;
                        index++;
                    }
                }
        }
        // 返回结果集
        return String.valueOf(result);
    }
}

题目来源:力扣(LeetCode)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值