栈适合解决需要后进先出(LIFO)的结构的算法题,例如:
我们下面会选择一部分题并用栈来进行解题:
思路
题意分析:要求将字符串中所有连续的字符删去,如下图所示:
解法:用栈模拟这个过程
代码
string removeDuplicates(string s) {
// 解法:用栈模拟过程
string st;
for(char ch : s)
{
if(!st.empty() && st.back() == ch)
st.pop_back();
else
st += ch;
}
return st;
}
思路
代码
bool backspaceCompare(string s, string t) {
// 栈模拟退格删除元素过程
string st1 = "";
for(char ch : s)
{
if(ch != '#')
st1.push_back(ch);
else if(ch == '#' && !st1.empty())
st1.pop_back();
}
string st2 = "";
for(char ch : t)
{
if( ch != '#')
st2.push_back(ch);
else if(ch == '#' && !st2.empty())
st2.pop_back();
}
return st1 == st2;
}
思路
题意分析:该题属于一个表达式求值题,即计算一个表示表达式的字符串的值。该题中s仅由’+‘、’-‘、’*‘、’/’ 四个符号组成。
解法:利用栈进行计算(数组表示栈)
代码
int calculate(string s) {
// 用一个栈存储数字字符,定义sym记录遇到的符号
// sym='+' : 直接将下一位tmp加到栈中
// sym='-' : 将-tmp加入到栈中
// sym='*' : 栈顶元素 *= tmp
// sym='/' : 栈顶元素 /= tmp
char sym = '+';
vector<int> st; // 数组作栈
int i = 0, n = s.size();
while(i < n)
{
if(s[i] == ' ') i++;
else if(s[i] >= '0' && s[i] <= '9')
{
int tmp = 0;
while(s[i] >= '0' && s[i] <= '9')
// 循环:tmp记录当前数字 并将其由字符串转为整形)
tmp = tmp * 10 + (s[i++] - '0');
if(sym == '+') st.push_back(tmp);
else if(sym == '-') st.push_back(-tmp);
else if(sym == '*') st.back() *= tmp;
else st.back() /= tmp;
}
else
{
sym = s[i++];
}
}
int ret = 0;
// 将栈中所有元素累加
for(auto x : st)
ret += x;
return ret;
}
思路
题意分析:看示例便很好理解,通过将 “数字[字符]” 解码为 “数字次字符串”
解法:利用栈进行计算/font>
代码
string decodeString(string s) {
// 栈模拟过程 : 字符串栈sst 整形栈 ist
vector<string> sst;
sst.push_back(""); // 初始化栈顶元素为空串
vector<int> ist;
// 遍历字符串,四种情况:
// 1. 遇到数字:放入ist
// 2. 遇到字符串 : 放到sst栈顶元素的后一位
// 3. 遇到左括号 : 将空字符串 "" 加入到 sst 的栈顶
// 4. 遇到右括号 : 合并两栈栈顶元素(即重复字符串)
int i = 0, n = s.size();
string tmp = "";
while(i < n)
{
if(s[i] >= '0' && s[i] <= '9')
{
int num = 0;
// 数字并不一定是个位、
while(isdigit(s[i]))
num = num * 10 + (s[i++] - '0');
ist.push_back(num);
continue;
}
else if(s[i] >= 'a' && s[i] <= 'z')
{
tmp = "";
while(s[i] >= 'a' && s[i] <= 'z' && i < n)
tmp += s[i++]; // 记录该字符串
sst[sst.size() - 1] += tmp; // 加到栈顶后一位
continue;
}
else if(s[i] == '[')
{
sst.push_back(""); // 新建空串
}
else // s[i] == ']'
{
// 合并两栈顶元素(重复字符串)
tmp = sst.back();
int x = ist.back();
ist.pop_back();
sst.pop_back();
while(x--)
sst.back() += tmp;
}
++i;
}
return sst.back();
}
思路
代码
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int> st; // 辅助栈
int cur1 = 0, cur2 = 0;
while (cur2 < popped.size())
{ // 出栈序列结束,则合法
if (!st.empty() && st.top() == popped[cur2])
{
st.pop();
cur2++;
}
else if (cur1 < pushed.size())
st.push(pushed[cur1++]);
else
return false;
}
return true;
}