news 2026/2/5 6:31:21

LeetCode 451 - 根据字符出现频率排序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 451 - 根据字符出现频率排序


文章目录

    • 摘要
    • 描述
    • 题解答案(整体思路)
      • 第一步:统计字符频率
      • 第二步:按频率排序
      • 第三步:按排序结果拼接字符串
    • 题解代码(Swift 可运行 Demo)
    • 题解代码分析
      • 1. 为什么用 Dictionary 统计?
      • 2. 排序这一步在干什么?
      • 3. 为什么不能一边统计一边排序?
      • 4. 字符拼接这一步为什么这样写?
    • 示例测试及结果
      • 示例 1
      • 示例 2
      • 示例 3
    • 实际场景结合
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

这道题看起来很简单:
统计字符出现次数,然后按次数排序。

但如果你真在工程里做过类似的事,比如:

  • 搜索关键词权重排序
  • 日志里统计最常出现的错误码
  • 文本分析中提取高频字符或 Token

你会发现这类问题的核心,其实是「频率统计 + 排序策略」。

LeetCode 451 正好是一个非常干净、非常标准的模板题,非常适合用来练:

  • 字符统计
  • 排序规则设计
  • Swift 中 Dictionary + Array 的组合用法

描述

题目给你一个字符串s,要求你:

  • 统计每个字符在字符串中出现的次数
  • 按出现频率从高到低排序
  • 相同字符必须放在一起
  • 如果频率相同,字符之间的相对顺序不重要

需要注意的几个点:

  • 大写字母和小写字母是不同字符
  • 字符串长度最大可以到5 * 10^5
  • 所以实现不能太“暴力”

题解答案(整体思路)

这道题的解法其实非常清晰,可以拆成三步:

第一步:统计字符频率

遍历字符串,用一个字典:

[Character:Int]

来记录每个字符出现的次数。

第二步:按频率排序

把字典转成数组:

[(Character,Int)]

然后按value(出现次数)做降序排序。

第三步:按排序结果拼接字符串

排序完成后,按顺序把字符重复count次,拼接成最终字符串。

题解代码(Swift 可运行 Demo)

下面是完整、可直接运行的 Swift 实现:

classSolution{funcfrequencySort(_s:String)->String{// 1. 统计字符频率varfreq:[Character:Int]=[:]forchins{freq[ch,default:0]+=1}// 2. 按出现次数降序排序letsorted=freq.sorted{$0.value>$1.value}// 3. 构造结果字符串varresult=""for(ch,count)insorted{result+=String(repeating:ch,count:count)}returnresult}}

题解代码分析

1. 为什么用 Dictionary 统计?

varfreq:[Character:Int]=[:]

这是最自然、也最直观的方式:

  • key是字符
  • value是出现次数

Swift 的Dictionary对这种计数场景支持得非常友好。

2. 排序这一步在干什么?

letsorted=freq.sorted{$0.value>$1.value}

sorted之后的数据结构其实是:

[(Character,Int)]

也就是一个(字符, 次数)的数组。

排序规则很简单:

  • 谁出现次数多,谁排前面

3. 为什么不能一边统计一边排序?

因为:

  • 统计是 O(n)
  • 排序是 O(k log k),k 是不同字符数量

混在一起只会让逻辑变复杂,不会更快。

4. 字符拼接这一步为什么这样写?

result+=String(repeating:ch,count:count)

这一步非常直观:

  • 一个字符出现几次,就拼接几次
  • 保证相同字符一定是连续的

同时也满足了题目「相同字母必须放在一起」的要求。

示例测试及结果

示例 1

letsolution=Solution()print(solution.frequencySort("tree"))

输出可能是:

eert

或者:

eetr

都是正确结果。

示例 2

print(solution.frequencySort("cccaaa"))

输出:

cccaaa

或者:

aaaccc

示例 3

print(solution.frequencySort("Aabb"))

输出:

bbAa

注意这里:

  • 'A''a'是不同字符
  • 大小写不会混在一起

实际场景结合

这道题的模式在实际开发中非常常见,比如:

  • 搜索系统里,统计关键词出现频率
  • 日志分析中,找最常见的错误类型
  • 文本分析中,做简单的词频或字符分布

把这套逻辑稍微改一下,就可以变成:

  • Top K 高频元素
  • 热词统计
  • 标签权重排序

时间复杂度

  • 统计频率:O(n)
  • 排序(字符种类数为 k):O(k log k)
  • 构造字符串:O(n)

总体时间复杂度:

O(n + k log k)

在实际情况下,k通常远小于n

空间复杂度

  • 字典存储频率:O(k)
  • 排序数组:O(k)
  • 结果字符串:O(n)

空间复杂度:

O(n + k)

总结

LeetCode 451 是一道非常「工程友好」的题:

  • 思路清晰
  • 模板性强
  • 非常适合拿来练 Swift 的集合操作
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/4 15:39:13

C 语言输入与输出(I/O)详解

C 语言输入与输出(I/O)详解 引言 C 语言作为一种广泛使用的编程语言,其输入与输出(I/O)操作是编程中不可或缺的部分。本文将深入探讨 C 语言中的输入与输出操作,包括标准输入输出、文件操作以及如何提高 I/O 效率。 标准输入输出 标准输入 在 C 语言中,标准输入通常…

作者头像 李华
网站建设 2026/2/5 5:42:14

软件测试成本的多维解析与优化路径

在软件开发的生命周期中,测试环节的成本投入直接影响项目的质量底线与商业回报。根据业界研究,测试成本通常占据项目总预算的15%-40%,这一比例在金融、医疗等高可靠性要求的领域甚至更高。对测试成本构成的深刻理解,不仅关乎资源调…

作者头像 李华
网站建设 2026/1/26 21:44:50

5-脱氧-L-阿拉伯糖—结构独特的稀有单糖,药物设计与合成化学的宝贵砌块 CAS:13039-56-0

5-脱氧-L-阿拉伯糖是一种天然存在但相对稀有的五碳脱氧单糖,其独特的L-构型与脱氧结构赋予其区别于常见D-型糖的化学与生物学特性。作为手性合成与药物化学中的高价值砌块,它正日益受到糖化学、抗感染药物研发及糖生物学研究领域的关注。化学信息化学名称…

作者头像 李华
网站建设 2026/2/3 13:51:53

2-乙酰胺基-1,3,4,6-四-O-乙酰基-2-脱氧-5-硫代-α-D-吡喃葡萄糖 —— 糖化学与药物研发的关键砌块 CAS:67561-97-1

2-乙酰胺基-1,3,4,6-四-O-乙酰基-2-脱氧-5-硫代-α-D-吡喃葡萄糖是糖化学与糖药物研究领域中一类重要的修饰单糖衍生物。作为5-硫代葡萄糖的结构前体与保护形式,它不仅是糖生物学基础研究的关键工具分子,更为开发新型糖基化抑制剂、糖模拟药物及诊断探针…

作者头像 李华
网站建设 2026/1/28 9:29:10

群体分析如何改变你的客户洞察

原文:towardsdatascience.com/how-cohort-analysis-can-transform-your-customer-insights-ff7e221b8fdc 尽管进行了数月的营销努力,但你的销售额仍在下降,客户参与度也在下降。出了什么问题?如果有一种方法可以精确地确定客户何时…

作者头像 李华
网站建设 2026/2/5 5:26:24

别再为BGM被下架了,可以生成带声音且无版权素材的AI,真的来了

我做自媒体这么多年,最怕的不是没灵感,而是“做完视频被版权一刀切”。BGM 要么平台判侵权,要么授权贵到离谱;环境音、拟音、人声配音更麻烦——自己录质量差,请配音师成本高、周期长。所以我一直在找一种东西&#xf…

作者头像 李华