题目描述
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
输入:"abbaca"
输出:"ca"
解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
提示:
-
-
S 仅由小写英文字母组成。
题解
思路:这道题可以利用”栈“来实现,如下图所示。如果栈为空,将当前的字符推入栈中;如果栈不为空,则比较当前的字符和栈顶元素,如果相同就弹出栈顶元素,如果不同就将当前元素推入栈。
代码(C++)
string removeDuplicates(string s) { stack<char> sta; //空栈不能调用top() for (int i = 0; i < s.size(); i++) { if (sta.empty()) sta.push(s[i]); else if (sta.top() == s[i]) sta.pop(); else sta.push(s[i]); } s = ""; while (!sta.empty()) { char temp = sta.top(); sta.pop(); s += temp; } //字符串翻转 for (int i = 0, j = s.size() - 1; i < j; i++, j--) { char temp = s[i]; s[i] = s[j]; s[j] = temp; } return s;
}
分析
-
时间复杂度:O(N),N为字符串的长度。
-
空间复杂度:O(N)。
在 C++ 语言中,std::string 类本身就提供了类似「入栈」和「出栈」的接口,因此我们可以直接将需要被返回的字符串作为栈即可。对于其他的语言,如果字符串类没有提供相应的接口,则需要在遍历完成字符串后,使用栈中的字符显式地构造出需要被返回的字符串。
代码(C++)
string removeDuplicates(string s) { string result = ""; for (char i : s) { if (result.empty() || i != result.back()) { result.push_back(i); } else { result.pop_back(); } } return result; }