用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
来源:力扣(LeetCode)
思路:定义两个栈st1 , st2 插入元素只靠st1,删除元素只靠st2
class CQueue {
stack<int> st1 , st2;
public:
CQueue() {//清空两个栈
while(!st1.empty())
{
st1.pop();
}
while(!st2.empty())
{
st2.pop();
}
}
void appendTail(int value) {
st1.emplace(value);
}
int deleteHead() {
if(st1.empty() && st2.empty())
{
return -1;
}
if(st2.empty())
{
while(!st1.empty())
{
st2.emplace(st1.top());
st1.pop();
}
}
int buf = st2.top();
st2.pop();
return buf;
}
};
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
来源:力扣(LeetCode)
看见这题的第一眼,我脑子里就闪过了栈,因为后缀表达式的它的运算都是依靠栈来实现的,
就因为栈的特性:先进后出
思路路路路路:
用哈希表存放6个括号及其对应的值(自定义,能配对就行了)
然后从左开始遍历字符串,遇见左括号就入栈,遇见右括号就看栈顶的括号是不是能与当前右括号配对,如果能配对,对应的左括号出栈,如果不能配对,就说明这字符串里的括号是无效的
特殊情况:没有左括号的情况
如果只有右括号,即栈里一直为空,但是我们还需要比较栈顶元素是否能配对呢,这时读取stack::top的话程序就会崩溃
class Solution {
public:
bool isValid(string s) {
stack<char> st;
bool res = true;
unordered_map<char , int> map =
{
{'(' , 1 },{')' , -1 },
{'[' , 2 },{']' , -2 },
{'{' , 3 },{'}' , -3 },
};
for(char ch : s)
{
int buf = map[ch];
if(buf > 0) st.push(ch);
//配对,以及处理特殊情况
else if(!st.empty() && buf + map[st.top()] == 0) st.pop();
else res = false;
}
//因为配对成功我们就出栈,所以如果最后栈里还有元素的话,
//就说明还有没配对成功的括号,就代表这个括号字符串无效
if(!st.empty()) res = false;
return res;
}
};
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
来源:力扣(LeetCode)
这题一开始自己用栈写了一会,被嵌套的括号搞傻了,没啥思路,就看了一下官方题解,没想到是要在栈上完成解码的过程,最后在填入到字符串内,我一开始就想着一边解码一边填入结果字符串,就没写出来。
思路:
最后说明一下:我在代码中用的是第二个栈来中转并得到临时字符串,但其实可以通过insert在临时字符串头部插入字符来直接构建整个临时字符串,没必要用第二个栈,我只是懒得改代码了而已
代码:
class Solution {
public:
string decodeString(string s) {
stack<char> st;
stack<char> buf;
for(char& ch : s)
{
if(ch != ']') st.push(ch);//如果字符是数字、字母和左括号就入栈
else//如果是右括号就开始解码
{
while(st.top() != '[')
{//把字符填入第二个栈
buf.push(st.top());
st.pop();
}
st.pop();//去掉栈内左括号
string temp;
while(!buf.empty())
{//利用第二个栈构建字符串
temp += buf.top();
buf.pop();
}
int num = 0;
int carry = 0;
while(!st.empty() && st.top() >= '0' && st.top() <= '9')
{//获取数字,因为数字可能是多位的
num += (st.top()-'0')*pow(10,carry++);
st.pop();
}
while(num>=1)
{//根据数字重复填入栈
for(char& ch : temp)
{
st.push(ch);
}
--num;
}
}
}
int size = st.size();
string res(size,'0');
for(--size;size>=0;--size)
{//根据栈 构建结果字符串
res[size] = st.top();
st.pop();
}
return res;
}
};