394. 字符串解码
题目解析:
通过题目分析:我们可以得出了解题目的意思,就是将括号进行去掉,然后把括号前面的数字进行重复括号中的内容,最后只剩下字符,即完成了字符串解码的操作!!
算法思路:
对于本题,我们可以采用栈的数据结构进行求解,因为我们每次进行解析的时候,当匹配到第一个右括号时, 我们只需要将其与其最近的左括号进行匹配,然后与其左括号之前的数字进行匹配展开即可完成第一次字符串的解析!
对此,我们可以创建两个栈结构,第一个用于存放数字,第二个用于存放字符串!然后我们开始进行遍历原字符串即可,对于遍历到原字符串的情况,大致分为以下四种情况!
1.孤零零的字符:当遇到孤零零的字符时,我们只需要将其尾插到字符栈顶字符串的后边即可!
2.数字:当遇到数字的时候,我们直接插入到数字栈中即可!
3.左括号:当遇到左括号时,我们需要进行统计左括号中的字符串,最后将左括号中的字符串插入到栈顶即可!
4.右括号:当遇到一个右括号时,说明我们已经可以进行解析一次,我们取出数字栈顶的元素和字符串栈顶的元素,我们首先要做的是保存字符串中栈顶的元素,然后进行pop操作,然后再将保存的字符串根据数字的个数,尾插到新的字符栈栈顶的后面即可!
对于上述的思路,希望下伙伴们下来自己画图模拟一下即可明白,本人在此就不画图了,希望不明白的小伙伴一定要画图模拟试一下,再来看一下这段文字讲述!
需要特别注意的是,我们首先要将栈中进行push一个空串,如果不进行push空串的操作!那么后面+=的操作一定会导致系统崩溃的问题!
代码:
class Solution {
public:
string decodeString(string s)
{
//题目分析可得!
//我们可以设置两个栈,一个为数字栈,一个为字符栈!
//数字栈存储着将要计算的数字!
//字符栈就是记录我们最终结果的栈!
stack<int>nums;
stack<string>str;
//首先一定要将str进行压栈,防止因为为空导致后面内存出错!
str.push("");
int len=s.size();
for(int i=0;i<len;)
{
//分为四种情况!
//ch为数字的时候,直接将该数字进行压栈即可!
if(s[i]>='0'&&s[i]<='9')
{
int tem=0;
while(s[i]>='0'&&s[i]<='9')
{
//存储多位数字!
tem=tem*10+(s[i]-'0');
i++;
}
nums.push(tem);
}
//ch为单独的字符串时,直接在字符栈中的栈顶元素后面进行尾插即可!!
else if(s[i]>='a'&&s[i]<='z')
{
str.top()+=s[i];
i++;
}
//当为左括号的时候,记录字母,将字母压入到字符串栈顶即可!!
else if(s[i]=='[')
{
//存储字符,将字符进行压栈即可!
string tem="";
++i;
while(s[i]>='a'&&s[i]<='z')
{
tem+=s[i];
i++;
}
str.push(tem);
}
//右括号的时候,需要将数字栈和字符串栈顶的元素统一拿出来,然后将栈顶更新即可!!
else //右括号!
{
string tem=str.top();
str.pop();
int count=nums.top();
nums.pop();
while(count--)
{
str.top()+=tem;
}
i++;
}
}
return str.top();
}
};
946. 验证栈序列
题目解析:
对于本题,相信大家也不陌生,我们平常做的都是本类型的选择题,那么本道题需要我们用代码来实现验证是否为栈序列, 我们画图都可以解决本道题,那么如何用代码实现呢?请看算法思路!
算法思路:
对与本题:我们只需要依次将入栈的数组进行入栈,然后判断是否满足出栈条件(即栈顶元素是否与当前出栈序列对应的元素相等!),进行出栈操作即可,最后当所有的元素入栈结束之后,判断栈是否为空即可!
代码:
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped)
{
//将pushed中的所有元素进行压栈,然后执行出栈操作!
//最后判断栈是否为空即可!
stack<int>st;
int j=0;
//j用于标记着该出那个元素了!!
for(auto &ch:pushed)
{
st.push(ch);
while(st.size()&&st.top()==popped[j])
{
st.pop();
j++;
}
}
return st.empty();
}
};
227. 基本计算器 II
题目解析:
题目的意思很简单,就是让我们模拟实现一种算法,只需要解决简单的加减乘除即可,没有小括号,最后将结果输出即可!
算法思路:
因为题目给出的只有加减乘除这些操作符,没有扩号这种优先级最高的操作符,所以我们仅需要创建一个数字栈用于存储要计算的数字即可,一旦碰到乘除操作,直接将栈顶元素进行更新即可。最后将栈中所有元素相加返回即可!
代码:
class Solution {
public:
int calculate(string s)
{
stack<int>st;
int len=s.size();
int i=0;
char op='+';
while(i<len)
{
if(s[i]==' ')
{
i++;
}
else if(s[i]>='0'&&s[i]<='9')
{
int tem=0;
while(i<len&&s[i]>='0'&&s[i]<='9')
{
tem=tem*10+(s[i]-'0');
i++;
}
if(op=='+')
{
st.push(tem);
}
else if(op=='-')
{
st.push(-tem);
}
else if(op=='*')
{
st.top()=st.top()*tem;
}
else
{
st.top()/=tem;
}
}
else
{
op=s[i];
i++;
}
}
int sum=0;
while(st.size())
{
sum+=st.top();
st.pop();
}
return sum;
}
};
844. 比较含退格的字符串
题目解析:
对于本题,我们要判断的是经过退格字符的转化,判断两个字符串是否相等!
算法思路:
对与本题的操作,我们依然可以利用栈先进后出的特性进行求解!但是我们不需要真正的使用栈这个数据结构,我们可以利用string来模拟栈进行求解-->步骤:进行遍历原字符串,若出现‘#’我们直接进行出栈(尾删对于字符串而言)操作即可,然后接着入栈,最终判断两字符串是否相等即可!
代码:
class Solution {
public:
bool backspaceCompare(string s, string t)
{
string a,b;
for(auto& ch:s)
{
if(a.size()&&ch=='#')
{
a.pop_back();
}
else if(ch!='#')
{
a+=ch;
}
}
for(auto& ch:t)
{
if(b.size()&&ch=='#')
{
b.pop_back();
}
else if(ch!='#')
{
b+=ch;
}
}
return a==b;
}
};
1047. 删除字符串中的所有相邻重复项
题目解析:
根据题意,可以得出,我们要进行删除相邻的重复项,然后返回删除后的结果即可!
算法分析:
我们仍然可以利用栈的数据结构进行求解,但是我们不用真的创建栈,可以用string模拟栈即可!
代码:
class Solution {
public:
string removeDuplicates(string s)
{
string ret; //用数组模拟栈!!
for(auto &ch:s)
{
//向ret中进行插入字符!
if(ret.size()&&ret.back()==ch)
{
ret.pop_back();
}
else
{
ret+=ch;
}
}
return ret;
}
};