堆栈我选择学习的内容有:
1.迷宫问题
2.表达式求值(有点小麻烦,之后再写>_<)
3.银行排队模拟
4.代码随想录中 堆栈力扣题
-------------------------------------------------------------------------------------------------------------------------------
1.迷宫问题(dfs非递归)深度优先搜索算法
这样的一个6x6的迷宫。其中最重要的是两个结构体,一个是用来存下一步方向的direction。另外一个是用来存每一步的状态的,其中不仅需要有当前的位置,还需要有下一步的放下,也就是box。其他具体实现细节可看b站up懒猫老师。
//迷宫问题
#include<iostream>
#include<stack>
#include<vector>
using namespace std;
typedef struct Direction{
int incX;
int incY;
};
typedef struct Box {
int x, y;//当前访问的迷宫格子的坐标
int di;//当前方向
};
bool findPath(vector<vector<int>> maze, Direction direct[], stack<Box>& s) {
Box temp;
int x, y, di;//当前位置以及方向
int x_next, y_next;//下一步的位置
int M = maze.size()-2;//行
int N = maze[0].size()-2;//列
maze[1][1] = -1;
temp.x = 1, temp.y = 1, temp.di = -1;
s.push(temp);
while (!s.empty()) {
temp = s.top();
s.pop();
x = temp.x; y = temp.y; di = temp.di + 1;
while (di < 4) {
x_next = x + direct[di].incX;
y_next = y + direct[di].incY;
if (maze[y_next][x_next] == 0) {//这里注意:我们用x表示横坐标,y表示纵坐标,但是要看maze对应位置,应该先传y
temp.x = x; temp.y = y; temp.di = di;
s.push(temp);
x = x_next; y = y_next;
maze[y_next][x_next] = -1;
if (x == N && y == M) return true;
else di = 0;
}
else {
di++;
}
}
}
return false;
}
int main() {
Direction direct[4];//
direct[0].incX = 1, direct[0].incY = 0;//向右移动
direct[1].incX = 0, direct[1].incY = 1;//向下移动
direct[2].incX = -1, direct[2].incY = 0;//向左移动
direct[3].incX = 0, direct[3].incY = -1;//向上移动
stack<Box> s;
vector<vector<int>>maze = { {1,1,1,1,1,1} ,
{1,0,0,1,1,1},
{1,0,0,0,0,1},
{1,0,1,1,1,1},
{1,0,0,0,0,1},
{1,1,1,1,1,1} };
if (findPath(maze, direct, s)) {
cout << "可以逃出迷宫" << endl;
while (!s.empty()) {
int x, y, di;
x = s.top().x;
y = s.top().y;
cout << "(" << x << "," << y << ")";
s.pop();
}
}
else {
cout << "死" << endl;
}
system("pause");
return 0;
}
------------------------------------------------------------------------------------------------------------------------------
4.力扣题
4.4有效括号
思路就是用一个栈来存这些括号,遇到左括号就存入,遇到右括号就去判断top是否和他是一对,如果是一对那就pop,不是就可以直接false;最后看栈是不是空就行。
但是,如果测试样例全是右括号的话也是不会入栈,所以我一开始的想法是先给这个栈push个字母i,看最后top是不是i,如果是那就true。
class Solution {
public:
bool isValid(string s) {
if(s.size()%2!=0) return false;
stack<char>st;
st.push('i');
for(char ch:s){
if(ch=='('){
st.push(')');
}
else if(ch=='{'){
st.push('}');
}
else if(ch=='['){
st.push(']');
}
else{
if(ch!=st.top()) return false;
else{
st.pop();
}
}
}
return st.top()=='i';
}
};
但是看了下其实有更好的解,就是在每次判断是否是一对的时候就去看这个栈是不是空的,如果是空的,这个还传一个右括号,那么就是false。
class Solution {
public:
bool isValid(string s) {
if(s.size()%2!=0) return false;
stack<char>st;
for(char ch:s){
if(ch=='('){
st.push(')');
}
else if(ch=='{'){
st.push('}');
}
else if(ch=='['){
st.push(']');
}
else{
if(st.empty()||ch!=st.top()) return false;//这里传入右括号的看下栈是否空
else{
st.pop();
}
}
}
return st.empty();
}
};
4.5 删除字符串中所有相邻重复项
class Solution {
public:
string removeDuplicates(string s) {
stack<char>st;
for(char ch:s){
if(st.empty()||st.top()!=ch){
st.push(ch);
}
else{
st.pop();
}
}
string ans;
while(!st.empty()){
ans +=st.top();
st.pop();
}
reverse(ans.begin(),ans.end());
return ans;
}
};
4.6逆波兰求值
这里题目已经简化了,已经给出了逆波兰表达式,直接堆栈就行。
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> number;
for(string ch:tokens){
if(ch=="+"||ch=="-"||ch=="*"||ch=="/"){
int num1 = number.top();
number.pop();
int num2 = number.top();
number.pop();
if(ch=="-") number.push(num2-num1);
if(ch=="+") number.push(num2+num1);
if(ch=="*") number.push(num2*num1);
if(ch=="/") number.push(num2/num1);
}
else{
number.push(stoi(ch));
}
}
return number.top();
}
};