Easy
题目描述
给你一个由小写英文字母组成的字符串 s,重复项删除操作会选择两个相邻且相同的字母,并将它们删除。
在 s 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后,返回最终的字符串。答案保证唯一。
示例 1:
输入:s = "abbaca"
输出:"ca"
解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
示例 2:
输入:s = "azxxzy"
输出:"ay"
提示:
- 1 <= s.length <= 10^5
- s 仅由小写英文字母组成。
解题思路
解题思路
这道题要求我们删除字符串中所有相邻的重复字符,直到无法再删除为止。我们可以用栈来高效解决这个问题。
栈的解法(推荐):
- 遍历字符串中的每个字符
- 如果栈为空,或者当前字符与栈顶字符不相同,将当前字符压入栈
- 如果当前字符与栈顶字符相同,说明找到了相邻重复项,将栈顶字符弹出(相当于删除这一对重复字符)
- 最后栈中剩余的字符就是结果
这种方法的巧妙之处在于,当我们遇到重复字符时,通过弹出栈顶元素来模拟删除操作。由于栈的后进先出特性,这样可以正确处理连续的删除操作。
字符串模拟解法: 也可以直接使用字符串来模拟栈的行为,不断检查字符串末尾是否与当前字符相同。
时间复杂度为 O(n),空间复杂度为 O(n),其中 n 是字符串长度。
代码实现
class Solution {
public:
string removeDuplicates(string s) {
string result;
for (char c : s) {
if (!result.empty() && result.back() == c) {
result.pop_back();
} else {
result.push_back(c);
}
}
return result;
}
};
class Solution:
def removeDuplicates(self, s: str) -> str:
stack = []
for c in s:
if stack and stack[-1] == c:
stack.pop()
else:
stack.append(c)
return ''.join(stack)
public class Solution {
public string RemoveDuplicates(string s) {
var result = new System.Text.StringBuilder();
foreach (char c in s) {
if (result.Length > 0 && result[result.Length - 1] == c) {
result.Remove(result.Length - 1, 1);
} else {
result.Append(c);
}
}
return result.ToString();
}
}
var removeDuplicates = function(s) {
const stack = [];
for (const c of s) {
if (stack.length > 0 && stack[stack.length - 1]
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | 需要遍历字符串一次,每个字符最多入栈出栈一次 |
| 空间复杂度 | O(n) | 最坏情况下栈需要存储所有字符 |
相关题目
. Removing Stars From a String (Medium)
. Minimize String Length (Easy)