总结:熟悉了栈和队列的性质以及操作方法,了解了队列和栈怎么样可以在功能上互相替代,熟悉了栈和队列的使用场景,解决一些匹配问题很方便。
232.用栈实现队列
题目链接:232. 用栈实现队列
思想:利用两个栈,先存入一个栈,等到输出的时候再把这个栈的元素全部压入另一个站,然后等另一个栈的栈顶元素pop之后。剩下的元素再压回原来的栈,这样就实现了队列的pop...
class MyQueue {
public:
stack<int> s1;
stack<int> s2;
MyQueue() {
}
//push元素则直接压入栈中
void push(int x) {
s1.push(x);
}
int pop() {
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
int number = 0;
if(!s2.empty()) number=s2.top();
s2.pop();
while(!s2.empty()){
s1.push(s2.top());
s2.pop();
}
return number;
}
int peek() {
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
int number = s2.top();
while(!s2.empty()){
s1.push(s2.top());
s2.pop();
}
return number;
}
bool empty() {
return s1.empty()&&s2.empty();
}
};
225. 用队列实现栈
题目链接:225. 用队列实现栈
思想:其实两个队列和一个队列都可以,较为简单的是使用一个队列,当你想输出栈顶的元素的时候,假设有n个元素,则把前n-1个元素出队再入队,剩下的那个元素就是要出栈的栈顶元素。如果要入栈的话和队列相同,直接入队就可以。
class MyStack {
public:
queue<int> ans;
int len;
MyStack() {
//默认无参构造 不动
len=0;
}
void push(int x) {
ans.push(x);
len++;//队列长度+1
}
int pop() {
//假设有里面有n个元素 则把前n-1个全部出队 再入队 然后队列开头剩出来的就是栈的top
for(int i=0;i<len-1;i++){
int number=ans.front();
ans.pop();
ans.push(number);
}
int res = ans.front();
ans.pop();
len--;
return res;
}
int top() {
for(int i=0;i<len-1;i++){
int number=ans.front();
ans.pop();
ans.push(number);
}
int number = ans.front();
//nt temp = ans.pop();
ans.pop();
ans.push(number);
return number;
}
bool empty() {
return ans.empty();
}
};
20. 有效的括号
题目链接:20. 有效的括号
思想:栈,遇到左括号就压入栈,遇到右括号就去检查他是否和栈顶元素对应,如果不对应或者栈为空的话就返回false。看最后栈剩了什么,如果不为空的话也返回false,为空就true。
class Solution {
public:
bool isValid(string s) {
//用栈就可以
//遇到左括号入栈 遇到右括号弹出
stack<char> stk;
for(int i=0;i<s.size();i++){
if(s[i]=='('||s[i]=='{'||s[i]=='[') stk.push(s[i]);
else{
if(s[i]==')'){
if(!stk.empty()&&stk.top()=='('){
stk.pop();
continue;
}
else return false;
}
else if(s[i]==']'){
if(!stk.empty()&&stk.top()=='['){
stk.pop();
continue;
}
else return false;
}
else{
if(!stk.empty()&&stk.top()=='{'){
stk.pop();
continue;
}
else return false;
}
}
}
return stk.empty();
}
};
1047. 删除字符串中的所有相邻重复项
思想:从字符串的开头入栈,看将要入栈的元素是否和栈顶元素相同,相同就把栈顶元素出栈,跳过当前的将要入栈的元素,直到所有元素都经历一遍整个过程。
class Solution {
public:
string removeDuplicates(string s) {
int counter = 0; // 记录一共遍历过的次数
// 答案栈
stack<char> stk1;
// 中转栈
stack<char> stk2;
// 如果有一次操作前后 答案栈的size不变 则说明完成所有删除操作
int size = s.size();
// 先压入答案栈 一轮之后 再把答案栈中的元素压入中转栈
// 然后重复之前的检测重复操作
for (int i = 0; i < s.size(); i++) {
// 如果栈不为空而且栈顶元素和s[i]相等 则弹栈 并跳过这个s[i]
if (!stk1.empty() && stk1.top() == s[i]) {
stk1.pop();
continue;
}
// 为空则直接入栈,两个值不相等也直接入栈
else
stk1.push(s[i]);
}
// 循环的操作:先全部放入中转栈 然后重新压入答案栈同时进行去重
while (size != stk1.size()) {
while (!stk1.empty()) {
stk2.push(stk1.top());
stk1.pop();
}
size=stk2.size();//记录下中转栈的元素个数
while (!stk2.empty()) {
if (!stk1.empty() && stk1.top() == stk2.top()) {
stk1.pop();
stk2.pop();
continue;
}
// 为空则直接入栈,两个值不相等也直接入栈
else
stk1.push(stk2.top());
stk2.pop();
}
}
string ans = "";
while(!stk1.empty()){
ans+=stk1.top();
stk1.pop();
}
reverse(ans.begin(),ans.end());
return ans;
}
};