#include <iostream>
using namespace std;
const int N = 1e5 + 10;
// 创建栈
int stk[N], n;
// 进栈 - 本质就是顺序表里面的尾插
void push(int x)
{
stk[++n] = x;
}
// 出栈 - 顺序表的尾删操作
void pop()
{
n--;
}
// 查询栈顶元素
int top()
{
return stk[n];
}
// 判断是否为空
bool empty()
{
return n == 0;
}
// 查询有效元素的个数
int size()
{
return n;
}
int main()
{
for(int i = 1; i <= 10; i++)
{
push(i);
}
// 当栈不为空的时候
while(size()) // while(!empty())
{
cout << top() << endl;
pop();
}
return 0;
}
class Solution
{
public:
string removeDuplicates(string s)
{
// 创建一个空的字符串 ret 用于存储结果
string ret;
// 遍历输入字符串 s 中的每一个字符
for(char ch : s)
{
// 如果 ret 非空,并且 ret 的最后一个字符等于当前字符
if(ret.size() && ret.back() == ch)
// 移除 ret 末尾的字符(即删除相邻的重复字符)
ret.pop_back();
else
// 否则,将当前字符添加到 ret 末尾
ret += ch;
}
// 返回最终去重后的字符串
return ret;
}
};
class Solution
{
public:
bool backspaceCompare(string s, string t)
{
// 创建两个空字符串 s1 和 s2 用于存储去除退格符后的结果
string s1, s2;
// 遍历字符串 s 处理退格符
for(char ch : s)
{
if(ch == '#') // 如果遇到退格符
{
if(s1.size()) // 如果 s1 非空
{
s1.pop_back(); // 删除 s1 最后一个字符
}
}
else s1 += ch; // 否则,将当前字符添加到 s1
}
// 遍历字符串 t 处理退格符
for(char ch : t)
{
if(ch == '#') // 如果遇到退格符
{
if(s2.size()) // 如果 s2 非空
{
s2.pop_back(); // 删除 s2 最后一个字符
}
}
else s2 += ch; // 否则,将当前字符添加到 s2
}
// 比较两个处理后的字符串是否相同
if(s2 == s1) return true;
else return false;
}
};
class Solution
{
public:
int calculate(string s)
{
// 使用栈来存储计算中的结果
vector<int> st;
int i = 0, n = s.size();
// 初始操作符为 '+', 表示第一个数字为正数
char op = '+';
while(i < n)
{
// 跳过空格
if(s[i] == ' ') i++;
// 如果是数字,读取整个数字
else if(s[i] >= '0' && s[i] <= '9')
{
int tmp = 0;
// 读取整个数字
while(i < n && s[i] >= '0' && s[i] <= '9')
tmp = tmp * 10 + (s[i++] - '0');
// 根据当前运算符执行相应的操作
if(op == '+')
st.push_back(tmp); // 加法:将数字压入栈
else if(op == '-')
st.push_back(-tmp); // 减法:将数字的相反数压入栈
else if(op == '*')
st.back() *= tmp; // 乘法:栈顶元素与当前数字相乘
else
st.back() /= tmp; // 除法:栈顶元素与当前数字相除
}
else
{
// 如果是运算符,更新当前操作符
op = s[i];
i++;
}
}
// 计算栈中所有数字的和
int ret = 0;
for(auto ch : st)
ret += ch;
return ret;
}
};
栈的使用:我们使用两个栈来辅助解码:
最后,栈中存储的是解码后的字符串,返回栈顶的字符串即为最终结果。
class Solution
{
public:
string decodeString(string s)
{
// 栈 st 用于存储解码过程中的中间字符串,栈 nums 用于存储数字
stack<string> st;
stack<int> nums;
st.push(""); // 初始栈顶为空字符串
int i = 0, n = s.size();
while(i < n)
{
// 处理数字:获取一个完整的数字(可能是多位数)
if(s[i] >= '0' && s[i] <= '9')
{
int tmp = 0;
while(i < n && s[i] >= '0' && s[i] <= '9')
{
tmp = tmp * 10 + (s[i++] - '0');
}
nums.push(tmp); // 将数字压入 nums 栈
}
// 处理左括号 '[',表示进入一个新的子字符串
else if(s[i] == '[')
{
i++;
string tmp = "";
// 读取子字符串中的字母
while(s[i] >= 'a' && s[i] <= 'z')
{
tmp += s[i];
i++;
}
st.push(tmp); // 将字母子串压入栈中
}
// 处理右括号 ']',表示子字符串结束,进行重复操作
else if(s[i] == ']')
{
string tmp = st.top();
st.pop(); // 弹出栈顶字符串(当前子字符串)
int k = nums.top();
nums.pop(); // 弹出栈顶数字(重复次数)
// 重复当前子字符串 k 次,并合并到栈顶字符串中
while(k--)
{
st.top() += tmp;
}
i++; // 处理下一个字符
}
// 处理字母,直接添加到栈顶字符串
else
{
string tmp;
while(i < n && s[i] >= 'a' && s[i] <= 'z')
{
tmp += s[i];
i++;
}
st.top() += tmp; // 将字母添加到栈顶字符串中
}
}
return st.top(); // 最终返回栈顶的解码结果
}
};
class Solution
{
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped)
{
int i = 0, j = 0, n = popped.size(); // i 是 pushed 的索引,j 是 popped 的索引
stack<int> st; // 栈,用于模拟压栈和弹栈操作
// 遍历 pushed 序列
while(i < n)
{
st.push(pushed[i++]); // 将当前元素压入栈中
// 检查栈顶元素是否等于 popped[j]
while(st.size() && st.top() == popped[j])
{
st.pop(); // 如果栈顶元素等于 popped[j],则弹出栈顶
j++; // 更新 popped 序列的索引
}
}
// 如果栈为空,且所有元素都能匹配成功,则返回 true
return st.empty();
}
};
栈算法的核心思路: