当前位置: 首页 > news >正文

python 字符串压缩(字符串-中等)含源码(九)

问题说明(含示例)

问题描述:实现字符串压缩功能,利用字符重复出现的次数,将连续重复的字符替换为 “字符 + 次数” 的形式。若压缩后的字符串长度未小于原字符串,则返回原字符串。字符串仅包含大小写英文字母(a-z, A-Z)。

示例

  1. 输入:"aabcccccaaa"输出:"a2b1c5a3"解释:连续字符分别为 "aa"(2 次)、"b"(1 次)、"ccccc"(5 次)、"aaa"(3 次),压缩后长度更短。

  2. 输入:"abbccd"输出:"abbccd"解释:压缩后为 "a1b2c2d1"(长度 7),比原字符串(长度 6)更长,故返回原字符串。

  3. 输入:"aaabccaaaaaddd"输出:"a3b1c2a5d3"解释:连续字符对应次数为 3、1、2、5、3,压缩后长度更短。

  4. 输入:"aabcaddd"输出:"aabcaddd"解释:压缩后为 "a2b1c1a1d3"(长度 10),比原字符串(长度 8)更长,故返回原字符串。

解题关键

核心思路是遍历字符串,统计连续重复字符的次数,拼接压缩结果后与原字符串比较长度,具体步骤:

  1. 特殊情况处理:若原字符串长度≤1,直接返回原字符串(无法压缩变短)。

  2. 初始化变量

    • result:用列表存储压缩后的字符和次数(列表拼接效率高于字符串);

    • prev_char:记录当前遍历的前一个字符(初始为字符串第一个字符);

    • count:记录当前字符连续出现的次数(初始为 1)。

  3. 遍历字符串(从第二个字符开始):

    • 若当前字符与 prev_char 相同,count += 1

    • 若不同,将 prev_char 和 count 加入 result,更新 prev_char 为当前字符,重置 count = 1

  4. 处理最后一组字符:遍历结束后,将最后一组 prev_char 和 count 加入 result

  5. 比较长度:将 result 转换为字符串,若长度 < 原字符串长度,返回压缩结果;否则返回原字符串。

对应代码

class Solution:def compressString(self, S: str) -> str:# 特殊情况:空字符串或长度为1的字符串,直接返回原字符串if len(S) <= 1:return S# 初始化变量:用列表存储结果(效率高于字符串拼接)result = []prev_char = S[0]  # 前一个字符,初始为第一个字符count = 1         # 连续出现的次数# 从第二个字符开始遍历for char in S[1:]:if char == prev_char:# 当前字符与前一个相同,次数+1count += 1else:# 不同字符:将前一个字符和次数加入结果,更新前一个字符和次数result.append(prev_char)result.append(str(count))prev_char = charcount = 1# 处理最后一组字符(循环结束后未加入的部分)result.append(prev_char)result.append(str(count))# 转换为字符串,比较长度compressed = ''.join(result)return compressed if len(compressed) < len(S) else S

对应的基础知识

实现该算法需掌握以下基础概念与操作:

  1. 字符串遍历与索引

    • 通过 for char in S[1:] 遍历字符串从第二个字符开始的所有元素;

    • 用 S[0] 访问字符串第一个字符,len(S) 获取字符串长度。

  2. 列表的拼接与转换

    • 用列表 result 存储中间结果,通过 append() 方法添加字符和次数(字符串拼接 += 效率低,因为字符串是不可变对象,每次拼接都会创建新对象);

    • 最终通过 ''.join(result) 将列表转换为字符串,效率高于多次字符串拼接

  3. 条件判断与计数更新

    • 核心逻辑 if char == prev_char: count += 1 else: ... 用于判断字符是否连续重复,更新计数或切换字符。

  4. 边界处理

    • 初始判断 if len(S) <= 1 处理短字符串(无法压缩变短),避免无效计算;

    • 遍历结束后手动添加最后一组字符,避免遗漏(因循环仅在字符变化时添加,最后一组无后续字符触发添加)。

对应的进阶知识

该问题的解决涉及字符串优化与复杂度分析的进阶思想:

  1. 时间与空间复杂度

    • 时间复杂度:O(n)n 为字符串长度),仅遍历一次字符串,列表 append 和 join 操作均为线性时间;

    • 空间复杂度:O(n),最坏情况下(所有字符均不重复),result 列表需存储 2n 个元素(每个字符 + 次数 “1”)。

  2. 字符串拼接的效率优化

    • Python 中字符串是不可变对象,使用 str += new_char 进行拼接时,每次都会创建新字符串(复制原有内容 + 新增部分),时间复杂度为 O(k)k 为当前字符串长度),总时间可能达到 O(n²)

    • 用列表 append 存储中间结果,最后 join 转换,总时间为 O(n)append 为 O(1) amortized,join 为 O(n)),是大规模字符串处理的推荐方式。

  3. 压缩逻辑的完整性

    • 计数为 1 时必须保留(如示例 2 中 “a” 压缩为 “a1”),否则会导致信息丢失(如 “ab” 压缩为 “ab” 与原字符串相同,但按规则需压缩为 “a1b1” 再比较长度);

    • 遍历结束后需手动添加最后一组字符,是因为循环仅在 “字符变化” 时触发添加,最后一组字符无后续变化,需单独处理。

编程思维与启示

  1. “效率优先” 的细节处理:选择列表而非字符串拼接,体现了对数据结构特性的理解 —— 针对频繁修改的场景,可变对象(列表)比不可变对象(字符串)更高效。

  2. “完整性” 的边界意识:遍历结束后处理最后一组字符,避免了 “循环漏处理” 的常见错误,体现了 “收尾逻辑” 的重要性(类似数组遍历中对最后一个元素的单独判断)。

  3. 条件反转” 的比较逻辑:最终返回 compressed if len(compressed) < len(S) else S,通过一次比较即可决定结果,避免冗余判断(无需单独判断 “大于” 或 “等于”)。

  4. 问题转化” 的简化思路:将 “压缩字符串” 问题转化为 “统计连续字符次数 + 拼接 + 长度比较” 的子问题,通过拆解步骤降低复杂度,这种 “分而治之” 的思维适用于多数字符串处理问题。

http://www.dtcms.com/a/460774.html

相关文章:

  • 如何自己设计一个网页宁波seo推广哪家好
  • 【STM32项目开源】STM32单片机智能温室大棚控制系统
  • 车牌 OCR 识别:国庆高速免费通行的 “隐形引擎”
  • wpf之TabControl
  • WPF应用最小化到系统托盘
  • 使用平行型子环腔的 23 KHz 线宽 1064 nm SOA 光纤激光器
  • 保定企业建站程序wordpress数据都被存在哪
  • 深圳做网站做app少儿戏曲知识 网站建设
  • SymPy 符号计算:从基础到高级的完整指南
  • 成免费crm推广网站黄石网站建设黄石
  • HTB Monitored writeup(nagios api v1 login)
  • 开源 C++ QT QML 开发(十三)多线程
  • 企业如何建设网站,企业搭建网站的流程
  • HarmonyOS SaveButton深度解析:安全便捷的媒体资源保存方案
  • 如何用开源外卖系统源码打造私域O2O生态?技术+运营双轮驱动
  • {title:敏捷开发实战如何利用Scrum框架在30天内交付高质量软件}
  • 浏览器端音视频处理新选择:Mediabunny 让 Web 媒体开发飞起来
  • iOS 26 能耗监测全景,Adaptive Power、新电池视图
  • 微软警告:攻击者将Microsoft Teams武器化用于勒索软件、间谍活动及社会工程攻击
  • QT MVC中View的特点及使用注意事项
  • WAF防护的性能优化策略
  • MyBatis-Spring集成完全指南
  • 如何知道自己的台式电脑的所有硬件信息
  • 门户网站 商城系统免费的网络推广
  • Arbess从入门到实战(9) - 使用Arbess+GitLab实现PHP项目自动化部署
  • .Net Core 在Linux系统下创建服务
  • Vue ASP.Net Core WebApi 前后端传参
  • IntelliJ IDEA 编译内存设置全攻略:Shared heap size vs User-local heap size 区别详解(2025版)
  • 恩施网站建设公司asp源码下载网站
  • 《考研408数据结构》第四章(串和串的算法)复习笔记