给定两个字符串 s
和 part
,我们需要对 s
执行以下操作,直到 s
中不再包含任何子串 part
:
每次找到 s
中最左边出现的 part
子串,并将其从 s
中删除。
最后,返回所有 part
都被删除后的最终字符串。
注意:
输入:s = "daabcbaabcbc", part = "abc"
输出:"dab"
解释:
- 删除 "abc"(下标 2)→ "dabaabcbc"
- 删除 "abc"(下标 4)→ "dababc"
- 删除 "abc"(下标 3)→ "dab"
输入:s = "axxxxyyyyb", part = "xy"
输出:"ab"
解释:
- 删除 "xy"(下标 4)→ "axxxyyyb"
- 删除 "xy"(下标 3)→ "axxyyb"
- 删除 "xy"(下标 2)→ "axyb"
- 删除 "xy"(下标 1)→ "ab"
这个问题的核心在于:
**part**
**part**
**s**
中不再包含 **part**
为止我们可以使用两种主要方法来实现这个过程:
str.replace()
+ while
循环每次使用 s.replace(part, "", 1)
,只替换最左边的一个子串,配合 while part in s
来不断迭代。
通过遍历字符串 s
,将字符逐一压入栈中,同时检查栈尾是否形成了 part
,一旦匹配,就从栈中删除对应部分。这种方法效率更高,不需要反复查找。
class Solution:
def removeOccurrences(self, s: str, part: str) -> str:
while part in s:
s = s.replace(part, "", 1) # 只替换最左边的一个 part
return s
s
的长度,M 是 part
的长度。class Solution:
def removeOccurrences(self, s: str, part: str) -> str:
stack = []
part_len = len(part)
for ch in s:
stack.append(ch)
if len(stack) >= part_len and ''.join(stack[-part_len:]) == part:
del stack[-part_len:]
return ''.join(stack)
s
。方法 | 时间复杂度 | 空间复杂度 | 易理解性 | 性能表现 |
---|---|---|---|---|
替换 + while | O(N * M) | O(1) | ⭐⭐⭐⭐ | ⭐⭐ |
栈模拟法 | O(N) | O(N) | ⭐⭐⭐ | ⭐⭐⭐⭐ |
字符串反复删除子串的问题虽然不难,但背后其实隐藏着不少值得深入思考的点:
如果面对较短的字符串或对执行效率不敏感,str.replace()
的方式已经足够使用。但若处理大规模字符串、或要求在性能敏感场景下运行,推荐使用栈模拟法,它可以将时间复杂度从 O(NM) 降为 O(N)。