从字符串中移除星号-LeetCode
2390. 从字符串中移除星号
🎯 问题描述
描述:
给你一个包含若干星号 * 的字符串 s。
s 中的操作如下:
- 选择
s中一颗星号*。 - 移除星号
*左侧最近的那个非星号字符,并移除星号本身。
题目数据保证总会存在可执行的移除操作。
请返回执行完所有操作后的字符串。
说明:
-
这是一个典型的栈应用问题。
-
核心策略:
- 我们可以把普通字符看作是“入栈”操作。
- 把星号
*看作是“出栈”操作(即删除最近加入的字符)。 - 遍历字符串,根据字符类型决定是添加还是删除。
-
示例:
-
示例 1:
1 | 输入:s = "leet**cod*e" |
💻 解题思路
思路1:栈模拟
核心逻辑
- 初始化:
- 创建一个空列表
ans作为栈,用于存储最终保留下来的字符。
- 创建一个空列表
- 遍历字符串:
- 遍历
s中的每一个字符ch。 - 情况 A:星号
*- 执行删除操作:弹出栈顶元素 (
ans.pop())。 - 题目保证操作总是可执行,所以不需要检查栈是否为空。
- 执行删除操作:弹出栈顶元素 (
- 情况 B:普通字符
- 执行添加操作:将字符压入栈 (
ans.append(ch))。
- 执行添加操作:将字符压入栈 (
- 遍历
- 构建结果:
- 遍历结束后,将栈中剩余的字符拼接成字符串返回 (
"".join(ans))。
- 遍历结束后,将栈中剩余的字符拼接成字符串返回 (
代码实现
1 | class Solution: |
📊 性能分析
- 时间复杂度:
- 其中 是字符串
s的长度。 - 我们只需要遍历一次字符串,每次操作(入栈、出栈)都是 。
- 最后的
join操作也是 。
- 其中 是字符串
- 空间复杂度:
- 我们需要一个栈来存储字符。
- 在最坏情况下(没有星号),栈的大小等于字符串长度。
思考
-
为什么不用字符串直接修改?
- 在 Python 中,字符串是不可变的。如果使用字符串切片(例如
s = s[:i] + s[i+2:])来删除字符,每次操作都需要创建一个新的字符串,时间复杂度会达到 ,在数据量大时会超时。 - 使用列表(栈)可以将删除操作优化到 。
- 在 Python 中,字符串是不可变的。如果使用字符串切片(例如
-
题目保证的有效性:
- 题目说明“保证总会存在可执行的移除操作”,这意味着当我们遇到
*时,栈中一定至少有一个字符。因此,代码中不需要写if ans:来检查栈是否为空,这简化了代码逻辑。
- 题目说明“保证总会存在可执行的移除操作”,这意味着当我们遇到
-
双指针法(进阶):
- 这道题也可以用双指针(或者叫“写入指针”)在 额外空间(如果不算结果字符串)下解决。
- 思路:维护一个写入指针
j。遍历字符串,如果是普通字符,写入j位置并j++;如果是*,则j--(相当于回退写入位置)。 - 虽然双指针空间更优,但栈解法逻辑更直观,且代码更简洁。
-
类似题目:
- 这道题与 LeetCode 844(比较含退格的字符串)非常相似,都是利用栈来处理“删除前一个字符”的逻辑。掌握这种模式可以解决一类问题。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






