1047. 删除字符串中的所有相邻重复项
借助栈结构,遍历字符串 放入一个字符前看看是否和栈顶元素相同,相同就出栈栈顶元素,如果为空或者不相等就入栈。遍历结束栈中剩余的字符就是目标结果。
我们可以用string来模拟栈,返回时就不用再从栈中获取返回结果。
class Solution {
public:
string removeDuplicates(string s) {
string re = "";
for (auto& c : s)
{
if (re == "" || c != re.back())
re += c;
else
re.pop_back();
}
return re;
}
};
227. 基本计算器 II
举个例子:4-3+6*4/2-123+34
需要一个数组模拟栈 一个字符代表运算符
4放入栈
- 更新字符为-
3 看字符是什么 是 - (后面可能是* / 先运算 )放入栈
+ 更新字符为+
6 看字符 放入栈
* 更新字符
4 看字符 为* 要先运算 取出栈顶元素*4 再入栈
...
这些数字都是单个字符,“123”怎么取?我们是正着遍历这个字符串,用tmp记录 tmp先*10再加当前字符代表的数字。
总结:遇到数字看当前字符是什么,是+ - 直接入栈 因为后面可能是* / 先运算。如果当前符号是* / 取出栈顶元素进行运算 再入栈。
s
由整数和算符('+', '-', '*', '/')
组成,中间由一些空格隔开。一个表达式中* / 优先运算,我们先把* / 先运算完,最后再把这些数加起来。
1.先用栈存储运算后的结果 char sym记录运算符(因为题目说所有数都是整数,所以sym初始化=+)
2.遍历表达式字符串
1.空格 跳过
2.数字 有可能是123多个字符 所以循环取。看当前sym是什么,
+直接入栈 -取反入栈 *乘栈顶 /除栈顶
3.运算符 对sym更新
3.最后遍历栈获取总和结果
class Solution {
public:
int calculate(string s) {
vector<int> mig;
int i=0,n=s.size();
char sym='+';
while(i<n)
{
//1.空格跳过
if(s[i]==' ') i++;
//2.字符是数字
else if(isdigit(s[i]))
{
int tmp=0;
while(i<n&&isdigit(s[i]))tmp=tmp*10+(s[i++]-'0');
if(sym=='+') mig.push_back(tmp);
if(sym=='-') mig.push_back(-tmp);
if(sym=='*') mig.back()*=tmp;
if(sym=='/') mig.back()/=tmp;
}
//3.运算符
else sym=s[i++];
}
int re=0;
for(auto&i:mig) re+=i;
return re;
}
};
394. 字符串解码
方法一:用一个栈进行模拟
class Solution { public: string decodeString(string s) { vector<string> re; int n = s.size(), i = 0; while (i < n) { // 1.数字 if (isdigit(s[i])) { string tmp; while (i < n && isdigit(s[i])) tmp += s[i++]; re.push_back(tmp); } // 2.[ 跳过 else if (s[i] == '[') i++; // re.push_back(string(1, s[i++])); // 3.字符串 else if (isalpha(s[i])) { string tmp; while (i < n && isalpha(s[i])) tmp += s[i++]; //如果栈顶是字符串就追加在栈顶 为空直接入栈 if(re.size()&&isalpha(re.back()[0])) { re.back() += tmp; } else re.push_back(tmp); } // 4.] else { i++; //1.获取字符串 并出栈 string s = re.back(); re.pop_back(); // //2.出栈[ // re.pop_back(); //3.获取重复次数 并出栈 int tmp = stoi(re.back()); re.pop_back(); //4.重复完成的字符串入栈 如果栈顶是字符串就追加在栈顶 为空直接入栈 string push; while (tmp--) push += s; if(re.size()&&isalpha(re.back()[0])) { re.back() += push; } else re.push_back(push); } } return re[0]; } };
方法二:用两个栈,一个栈记录字符串 一个记录数字
分4种情况
1.数字 入数字栈
2.[ 把 [ 后面的字符串push到字符串栈
3.] 从两个栈中取出top元素并pop 复制后top()+=累加到栈顶元素
4.单独的字符串 top()+=累加栈顶元素后面
因为字符串栈有可能为空 不能top+=累加 所以先加入"" 空字符串 防止越界访问
class Solution {
public:
string decodeString(string s) {
stack<string> st;
stack<int> nums;
//防止栈为空 top出错
st.push("");
int i=0,n=s.size();
while(i<n)
{
//1.数字:提取放入nums栈
if(isdigit(s[i]))
{
int tmp=0;
//因为数字后面必定是[ 所以不用判断i<n
while(isdigit(s[i])) tmp=tmp*10+s[i++]-'0';
nums.push(tmp);
}
//2.[ :把后面字母字符串放入 st栈中
else if(s[i]=='[')
{
i++;
string tmp;
while(isalpha(s[i])) tmp+=s[i++];
st.push(tmp);
}
//3.]:重复 并放入栈顶字符串的后面
else if(s[i]==']')
{
i++; //跳过]
string tmp=st.top(); st.pop();
int n=nums.top(); nums.pop();
while(n--)
{
st.top()+=tmp;
}
}
//4.单独字母字符串:提取出来并放入栈顶字符串后面
else
{
string tmp;
while(i<n&&isalpha(s[i])) tmp+=s[i++];
st.top()+=tmp;
}
}
return st.top();
}
};