栈,是限定仅在表尾进行插入或删除操作的线性表。因此,对栈来说,表尾端有其特殊的含义,称为栈顶;相应的,表头端称为栈底。不含元素的空表称为空栈。
栈的特点:后进先出
C++ STL stack的使用方法:
引入:
stack定义在<stack>头文件中,需要引入<stack>头文件。
#include <stack>
定义栈:
stack<数据类型> 变量名;
例如:stack<char> s;
stack<string> str;
基本操作:
入栈:
变量名.push(元素);
例如:s.push(x);
出栈:
变量名.pop();
例如:s.pop();
注意:出栈操作仅将栈顶元素删除,并不会返回栈顶元素。
获取栈顶元素:
变量名.top();
例如:char ch = s.top();
判断栈空:
变量名.empty();
例如:s.empty();
(当栈空是为true,否则为false)
栈的元素个数:
变量名.size();
例如:s.size();
(获取栈中的元素个数)
Question No.1
有效的括号
https://leetcode.cn/problems/valid-parentheses/
思路:首先获取字符串的元素个数,判断是否是奇数,如果是奇数,直接返回false
;然后建立栈,遍历给定的字符串。如果字符是右括号,我们可以直接将其入栈,否则就需要先判断栈是否为空,因为先出现左括号注定无法匹配;然后判断字符中的左括号是否和栈顶的右括号匹配。匹配则继续,不匹配直接返回false
;最后在遍历结束后,判断栈是否为空,为空返回true
,否则返回false
。
class Solution {
public:
bool isValid(string s) {
int n = s.size();
if(n % 2 == 1) return false;
stack<char> str;
for(char ch : s ){
if(ch == '(' || ch =='[' || ch == '{') str.push(ch);
else if(str.size() == 0) return false;
else if(ch == ')' ){
if(str.top() != '(') return false;
else str.pop();
}else if(ch == ']'){
if(str.top() != '[') return false;
else str.pop();
}else if(ch == '}'){
if(str.top() != '{') return false;
else str.pop();
}
}
if(str.size() == 0) return true;
else return false;
}
};
Question No.2
逆波兰表达式求值
https://leetcode.cn/problems/evaluate-reverse-polish-notation/
逆波兰式:https://baike.baidu.com/item/逆波兰式/128437
思路:遍历字符串数组tokens,用字符串最后一位判断是否是数值(之所以不用第一位判断是因为存在负数),如果是数值,则使用stoi
将字符串转换为数值。如果不是数值,则获取上两个元素取出,进行运算,再将运算得到的新值入栈。
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<long long> s;
for(string& token : tokens){
if(token[token.size()-1] >= '0' && token[token.size()-1] <= '9'){
s.push(stoi(token));
}else{
long long b = s.top();
s.pop();
long long a = s.top();
s.pop();
s.push(calc(a,b,token));
}
}
return s.top();
}
long long calc(long long a, long long b, string op){
if(op == "+") return a + b;
if(op == "-") return a - b;
if(op == "*") return a * b;
if(op == "/") return a / b;
return 0;
}
};
Question No.3
字符串消除
https://www.acwing.com/problem/content/description/4507/
#include<iostream>
#include<stack>
using namespace std;
int main()
{
string s;
cin >> s;
stack<char> stack;
int n = 0; // 记录可以消除多少对[两个连续且相同的字母]
for(int i = 0;i < s.size();i++){
// 如果栈中元素个数大于0,并且当前字符与栈顶元素相同
if(stack.size() > 0 && s[i] == stack.top()){
stack.pop();
n++;
}else{
stack.push(s[i]);
}
}
if(n % 2 == 1) cout << "Yes";
else cout << "No";
return 0;
}