代码随想录训练营第十一天
232.用栈实现队列
使用栈实现队列的下列操作:
push(x) – 将一个元素放入队列的尾部。
pop() – 从队列首部移除元素。
peek() – 返回队列首部的元素。
empty() – 返回队列是否为空。
栈直接使用C++ STL库中的stack使用两个栈,一个用于存,一个用于取,就可以将压入栈的数据按照先进先出的原则实现一个队列的功能
代码如下:
class Solution0//用栈模仿队列
{
public:
stack<int> stIne;
stack<int> stOut;
void push(int n)
{
stIne.push(n);
return;
}
int pop()
{
if (stOut.empty())//当栈为空的时候返回真值
{
while (!stIne.empty())
{
int a = stIne.top();
stIne.pop();
stOut.push(a);
}
}
int a = stOut.top();
stOut.pop();
return a;
}
int peek()
{
if (!empty())
{
return -1;
}
else
{
int a = pop();
stOut.push(a);
return a;
}
}
bool empty()
{
if (stIne.empty()&&stOut.empty())
{
return true;
}
else
{
return false;
}
}
};
225.用队列实现栈
使用队列实现栈的下列操作:
push(x) – 元素 x 入栈
pop() – 移除栈顶元素
top() – 获取栈顶元素
empty() – 返回栈是否为空
注意:
你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。
使用一个队列保存所有的数据,另一个队列用于在将数据压出栈和寻找栈顶数据时作为中间过渡
代码如下:
class Solution
{
public:
queue<int> quIne;
queue<int> quOut;
void push(int n)
{
quIne.push(n);
return;
}
void pop()
{
int size = quIne.size();
int l = size-1;
if (quIne.empty())
return;
else
{
while (l--)
{
int a = quIne.front();
quOut.push(a);
quIne.pop();
}
quIne.pop();
l = size - 1;
while (l--)
{
int a = quOut.front();
quIne.push(a);
quOut.pop();
}
}
return;
}
bool empty()
{
return quIne.empty() ? true : false;
}
int peek()
{
int size = quIne.size();
int l = size - 1;
while (l--)
{
int a = quIne.front();
quOut.push(a);
quIne.pop();
}
int result = quIne.front();
quIne.pop();
l = size - 1;
while (l--)
{
int a = quOut.front();
quOut.pop();
quIne.push(a);
}
quIne.push(result);
return result;
}
};
20.有效括号
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
在开始算法前需要指定一个标志sign,并初始化为true,使用一个栈存放所有的合法的前括号,然后当出现后括号时,如果当前字符是与栈顶相匹配的后括号时,将栈顶压出栈,并继续向后读如字符串,当不匹配时,读入字符串结束,并将标志sign置为false,认为该字符串中的前后括号不匹配,当字符全部读入完毕,栈为空并且标志sign为true时,认为该字符串中存在有效的括号,否则不匹配。
代码如下:
class Solution
{
public:
bool isValid(string& s)
{
stack<char> stackValid;
bool sign = true;
int len = s.size();
for (int i=0;i<len;i++)
{
if (s[i] == '(')
stackValid.push(s[i]);
else if (s[i]=='{')
{
stackValid.push(s[i]);
}
else if (s[i]=='[')
{
stackValid.push(s[i]);
}
else if (s[i]==')')
{
if (!stackValid.empty()&&stackValid.top()=='(')
{
stackValid.pop();
}
else
{
sign = false;
break;
}
}
else if (s[i]=='}')
{
if (!stackValid.empty()||stackValid.top()=='(')
{
stackValid.pop();
}
else
{
sign = false;
break;
}
}
else if (s[i]=='}')
{
if (!stackValid.empty()&&stackValid.top()=='{')
{
stackValid.pop();
}
else
{
sign = false;
break;
}
}
}
return stackValid.empty() && sign ? true : false;
}
};
1047. 删除字符串中的所有相邻重复项
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
输入:“abbaca”
输出:“ca”
解释:例如,在 “abbaca” 中,我们可以删除 “bb” 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 “aaca”,其中又只有 “aa” 可以执行重复项删除操作,所以最后的字符串为 “ca”。
与上题相似,不同的是将字符串压入栈,当栈为空或者当前读入字符串与栈顶不相同时将当前字符压入栈,当栈非空且当前读入的字符与栈顶字符相同时,将栈顶压出,最后还需要借助另外一个栈,将前一个栈中的元素全部压入,然后再出栈恢复原来元素间的顺序。
代码如下:
class Solution
{
public:
string removeDuplicates(string& s)
{
string result;
stack<char> stackStr;
stack<char> stackOrder;
for (int i=0;i<s.size();i++)
{
if (!stackStr.empty()&&stackStr.top()==s[i])
{
stackStr.pop();
}
else
{
stackStr.push(s[i]);
}
}
while (!stackStr.empty())
{
stackOrder.push(stackStr.top());
stackStr.pop();
}
while (!stackOrder.empty())
{
result.push_back(stackOrder.top());
stackOrder.pop();
}
return result;
}
};