LeetCode 面试题 01.06. 字符串压缩(443. 压缩字符串)

2023-12-26 18:04

本文主要是介绍LeetCode 面试题 01.06. 字符串压缩(443. 压缩字符串),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 对于算法题,按题型类别刷题才会更有成效,因此我这里在网上搜索并参考了下 “🔥 LeetCode 热题 HOT 100” 的题型归类,并在其基础上做了一定的完善,希望能够记录自己的刷题历程,有所收获!点击下发链接跳转~⬇️⬇️⬇️

🔥 LeetCode 热题 HOT 100【题型归类汇总,助力刷题】

面试题 01.06. 字符串压缩

   

字符串压缩。利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串aabcccccaaa会变为a2b1c5a3。若“压缩”后的字符串没有变短,则返回原先的字符串。你可以假设字符串中只包含大小写英文字母(a至z)。

示例1:

 输入:"aabcccccaaa"
 输出:"a2b1c5a3"

示例2:

 输入:"abbccd"
 输出:"abbccd"
 解释:"abbccd"压缩后为"a1b2c2d1",比原字符串长度更长。

提示:

  1. 字符串长度在[0, 50000]范围内。

思路:参考 LeetCode题解

根据题意,需要将「连续相同字符」压缩为「字符+出现次数」的格式。例如:aaa→a3,b→b1,aabbb→a2b3

双指针法

  • 分别定义下标 i = 0(慢指针),j = 1 (快指针)。
  • 令 i 指向字符串的「首个字符」, j 向前遍历,直到访问到「不同字符」时停止,此时 j−i 便是「首个字符」的连续出现次数,即可完成首个字符的压缩操作。
  • 接下来,从下个字符开始,重复以上操作,直到遍历完成即可。
  • 根据题目要求,最终返回「原字符串」和「压缩字符串」中长度较短的那个。

注意

在golang中,常规的字符串拼接方式,其性能较差,例如:“大量使用切片表达式” 和 “+ 运算符”会频繁内存分配,最终导致性能较差。

所以 在 golang 中,有大量字符串拼接的场景下,不建议直接使用 “+” 运算符来拼接字符串,以避免频繁的内存分配问题。

我们在以上思路的基础上做性能优化:

  • 使用byte数组:提前预估好容量大小,例如 方法2
  • 使用 strings.Builder:例如 方法3

string类型的 原理解析

  • 在底层,string类型的值会被存储在连续内存空间中(byte类型的字节数组)。而大量使用切片表达式和“+”运算符会导致频繁内存分配。
  • 因此,这些对string的操作相当于对底层字节数组进行操作,会导致更多的内存重分配开销,影响性能。

时间复杂度:O(N)

其中 N 为输入字符串 S 长度。指针 i , j 皆完成一次字符串遍历,循环 N+N=2N 次,使用 O(N) 线性时间。

空间复杂度:O(N)

res 用于临时存储压缩结果。最差情况下(当原字符串的所有相邻字符都不同时,a→a1 一个变两个),压缩字符串的长度为 2N,占用 O(2N)=O(N) 大小的额外空间。

// 版本1 字符串拼接(性能不佳)
// 在底层,string的值会被存储在连续内存空间中(字节数组)。
// 大量使用切片表达式和“+”运算符会导致频繁内存分配。
// 因此,这些对string的操作相当于对底层字节数组进行操作,会导致更多的内存重分配开销,影响性能。
func compressString(S string) string {sLen := len(S)if sLen <= 1 {return S}res := ""i, j := 0, 1for ; j < sLen; j++ {if S[i] != S[j] {res += string(S[i]) + strconv.Itoa(j-i)i = j}if len(res) >= sLen {return S}}// 在for循环中,S末尾的结果集还未处理,这里需要追加上来res += string(S[i]) + strconv.Itoa(j-i)// 若“压缩”后的字符串没有变短,则返回原先的字符串if len(res) >= sLen {return S}return res
}// 版本2:使用byte数组优化
func compressString(S string) string {sLen := len(S)if sLen <= 1 {return S}// 数组提前预估容量,避免重分配res := make([]byte, 0, sLen)i, j := 0, 1for ; j < sLen; j++ {if S[i] != S[j] {res = append(res, S[i])res = append(res, []byte(strconv.Itoa(j-i))...)// 这两个append的操作要分开写,不支持合并一起写;后面同理// res = append(res, S[i], byte(strconv.Itoa(j-i))) // 错误i = j}if len(res) >= sLen {return S}}res = append(res, S[i])res = append(res, []byte(strconv.Itoa(j-i))...)// 若“压缩”后的字符串没有变短,则返回原先的字符串if len(res) >= sLen {return S}return string(res)
}// 版本3:使用go strings.Builder优化
func compressString(S string) string {sLen := len(S)if sLen <= 1 {return S}// res := ""var sb strings.Builderi, j := 0, 1for ; j < sLen; j++ {if S[i] != S[j] {sb.WriteByte(S[i])sb.WriteString(strconv.Itoa(j - i))// res += string(S[i]) + strconv.Itoa(j-i)i = j}}sb.WriteByte(S[i])sb.WriteString(strconv.Itoa(j - i))// res += string(S[i]) + strconv.Itoa(j-i)if sb.Len() >= sLen {return S}return sb.String()
}

这篇关于LeetCode 面试题 01.06. 字符串压缩(443. 压缩字符串)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/540342

相关文章

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

使用Python实现矢量路径的压缩、解压与可视化

《使用Python实现矢量路径的压缩、解压与可视化》在图形设计和Web开发中,矢量路径数据的高效存储与传输至关重要,本文将通过一个Python示例,展示如何将复杂的矢量路径命令序列压缩为JSON格式,... 目录引言核心功能概述1. 路径命令解析2. 路径数据压缩3. 路径数据解压4. 可视化代码实现详解1

Java中字符串转时间与时间转字符串的操作详解

《Java中字符串转时间与时间转字符串的操作详解》Java的java.time包提供了强大的日期和时间处理功能,通过DateTimeFormatter可以轻松地在日期时间对象和字符串之间进行转换,下面... 目录一、字符串转时间(一)使用预定义格式(二)自定义格式二、时间转字符串(一)使用预定义格式(二)自

SpringBoot使用GZIP压缩反回数据问题

《SpringBoot使用GZIP压缩反回数据问题》:本文主要介绍SpringBoot使用GZIP压缩反回数据问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot使用GZIP压缩反回数据1、初识gzip2、gzip是什么,可以干什么?3、Spr

如何使用Nginx配置将80端口重定向到443端口

《如何使用Nginx配置将80端口重定向到443端口》这篇文章主要为大家详细介绍了如何将Nginx配置为将HTTP(80端口)请求重定向到HTTPS(443端口),文中的示例代码讲解详细,有需要的小伙... 目录1. 创建或编辑Nginx配置文件2. 配置HTTP重定向到HTTPS3. 配置HTTPS服务器

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

一文详解如何在Python中从字符串中提取部分内容

《一文详解如何在Python中从字符串中提取部分内容》:本文主要介绍如何在Python中从字符串中提取部分内容的相关资料,包括使用正则表达式、Pyparsing库、AST(抽象语法树)、字符串操作... 目录前言解决方案方法一:使用正则表达式方法二:使用 Pyparsing方法三:使用 AST方法四:使用字

Java字符串处理全解析(String、StringBuilder与StringBuffer)

《Java字符串处理全解析(String、StringBuilder与StringBuffer)》:本文主要介绍Java字符串处理全解析(String、StringBuilder与StringBu... 目录Java字符串处理全解析:String、StringBuilder与StringBuffer一、St

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St