栈结构在算法题中的五种经典应用
栈(Stack)作为数据结构中最基础也最强大的工具之一,其'后进先出'的特性在处理匹配、撤销、优先级等问题时往往能化繁为简。本文将通过五道经典的 LeetCode 题目,深入剖析栈在不同场景下的实战用法,并给出 C++ 实现方案。
1. 删除字符串中的所有相邻重复项
问题描述:
给定一个由小写字母组成的字符串 s,反复删除其中相邻且相同的字符对,直到无法再删除为止。返回最终结果。
解题思路:
这道题很像'消消乐'。我们需要不断比较当前字符与前一个字符是否相同。如果相同则消除,不同则保留。虽然可以使用标准库的 std::stack,但考虑到最后需要还原字符串,直接用 std::string 或 vector<char> 模拟栈操作会更高效——利用尾插和尾删即可实现进栈和出栈。
C++ 实现:
class Solution {
public:
string removeDuplicates(string s) {
string ret;
for (int i = 0; i < s.size(); i++) {
// 如果栈不为空且栈顶元素与当前字符相同,则弹出(消除)
if (!ret.empty() && ret.back() == s[i]) {
ret.pop_back();
} else {
// 否则压入当前字符
ret.push_back(s[i]);
}
}
return ret;
}
};
2. 比较含退格的字符串
问题描述:
给定两个字符串 S 和 T,其中 '#' 代表退格键。判断在应用所有退格操作后,两个字符串是否相等。
解题思路:
退格操作天然符合栈的特性:输入字符进栈,遇到 '#' 则出栈。我们可以分别用两个数组模拟栈处理这两个字符串,最后比较栈内剩余内容是否一致。注意处理连续退格导致栈为空的情况。
C++ 实现:
class Solution {
public:
bool backspaceCompare(string s, string t) {
vector<char> stack1, stack2;
( c : s) {
(c != ) {
stack(c);
} (!stack()) {
stack();
}
}
( c : t) {
(c != ) {
stack(c);
} (!stack()) {
stack();
}
}
stack1 == stack2;
}
};


