You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

面试题:按字符出现次数升序生成指定字符串的字符图案

问题拆解与解决方案

你的代码主要卡在三个地方:频率统计效率低、排序逻辑未实现、图案生成缺失,下面一步步给你修正:

一、高效统计字符频率(替换嵌套循环)

原来的嵌套循环遍历字符串统计频率,不仅时间复杂度高(O(n²)),还容易出现重复统计的问题。用单次遍历+HashMap的getOrDefault方法就能简洁完成统计:

String test = "abbccbddddeeeee";
Map<Character, Integer> freqMap = new HashMap<>();

// 一次遍历完成所有字符的频率统计
for (char c : test.toCharArray()) {
    // 字符存在则取当前值+1,不存在则默认0+1
    freqMap.put(c, freqMap.getOrDefault(c, 0) + 1);
}

二、按频率升序排序字符

HashMap本身是无序的,你原来的代码试图维护两个独立列表排序,但仅实现了寻找最小值的逻辑,没有完成元素交换,等于没真正排序。直接将Map的键值对转为列表,自定义排序规则即可:

// 将Map的键值对转为列表,方便排序操作
List<Map.Entry<Character, Integer>> sortedEntries = new ArrayList<>(freqMap.entrySet());

// 排序规则:优先按出现次数升序,次数相同时按字符本身顺序(可选,根据需求调整)
sortedEntries.sort((entry1, entry2) -> {
    int freqDiff = entry1.getValue() - entry2.getValue();
    if (freqDiff != 0) {
        return freqDiff;
    }
    // 次数相同时按字母顺序排列,避免排序结果混乱
    return entry1.getKey() - entry2.getKey();
});

三、生成指定对齐图案

要实现题目要求的右对齐效果,先找到出现次数最多的字符长度,以此为基准计算每行需要补充的空格数,再重复打印对应字符:

// 获取最大出现次数,用于计算每行的空格补位
int maxCount = sortedEntries.stream()
                           .mapToInt(Map.Entry::getValue)
                           .max()
                           .orElse(0);

// 遍历排序后的结果,逐行打印图案
for (Map.Entry<Character, Integer> entry : sortedEntries) {
    char c = entry.getKey();
    int count = entry.getValue();
    // 空格数 = 最大次数 - 当前字符的出现次数
    int spaceNum = maxCount - count;
    // 先打印空格补位,再打印重复的字符
    System.out.print(" ".repeat(spaceNum));
    System.out.println(String.valueOf(c).repeat(count));
}

原有代码的核心问题

  1. 频率统计逻辑冗余:嵌套循环重复遍历字符串,效率低下,getOrDefault方法可一步完成统计
  2. 排序逻辑未落地:仅尝试寻找最小值,未对列表元素进行交换排序,直接操作Map条目列表是更简洁的方式
  3. 图案生成逻辑缺失:完全没有实现右对齐和字符重复打印的逻辑,需要通过空格补位+字符串重复完成

运行上述完整代码,输入"abbccbddddeeeee"会得到与题目一致的输出:

a
   cc
   bbb
   dddd
   eeeee

内容的提问来源于stack exchange,提问作者Avisek Adhikari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 23:45:43