1.有效的括号
cpp
class Solution {
public:
bool isValid(string s) {
stack<char> mystack;
for(int i=0;i<s.size();i++){
if(s[i]=='('||s[i]=='{'||s[i]=='[') mystack.push(s[i]);
else if(s[i]==')'){
if(!mystack.empty()&& mystack.top()=='(') mystack.pop();
else return false;
}
else if(s[i]==']'){
if(!mystack.empty()&&mystack.top()=='[') mystack.pop();
else return false;
}
else if(s[i]=='}'){
if(!mystack.empty()&&mystack.top()=='{') mystack.pop();
else return false;
}
}
return mystack.empty();
}
};
2.最小栈
(1)我的投机取巧版本
用了个数组来维护,注意private声明成员变量,但我这个其实有问题,出现重复元素的时候就可能寄了
cpp
class MinStack {
private:
stack<int> mystack; // 声明为成员变量
vector<int> minElement; // 声明为成员变量,或者可以用另一个栈
public:
MinStack() {
// 构造函数不需要初始化这些,它们会自动初始化
}
void push(int val) {
mystack.push(val);
if(minElement.empty() || val <= minElement.back()) {
minElement.push_back(val);
}
}
void pop() {
if(mystack.top() == minElement.back()) {
minElement.pop_back();
}
mystack.pop();
}
int top() {
return mystack.top();
}
int getMin() {
return minElement.back();
}
};
(2)
发现别人也是这么搞的,我的数组相当于一个栈。
3.字符串解码
抄的别人的思路,有几个点我需要过拟合
stack<pair<sring,int>> 还有就是res代表当前处理的串,cur表示重复的,注意一碰到左括号有个重置的操作,你感受一下,就是先把res放进去,然后让res为空。cur+pre=res
有点乱,也许可以背下来
cpp
class Solution {
public:
string decodeString(string s) {
stack<pair<string,int>> st;
int num=0;
string res;
for(char c: s){
if(isdigit(c))
num=num*10+(c-'0');//转换数字
else if(c=='['){
st.push(make_pair(res,num));
res="";
num=0;
}
else if(c==']'){
string pre=st.top().first;
int n=st.top().second;
string cur;
while(n--)
cur+=res;
res=pre+cur;
st.pop();
}else {
res+=c;
}
}
return res;
}
};
4.每日温度
用一个索引相减来存储距离,非常不错,还有就是要在while判断栈顶元素的温度是不是小于当前的,要不然会有问题的!
cpp
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
stack<pair<int,int>> st;
vector<int> res(temperatures.size(),0);//初始化
for(int i=0;i<temperatures.size();i++){
int temperature=temperatures[i];
auto p=make_pair(temperature,i); //记录索引
while(!st.empty()&&st.top().first<temperature){//在while判断,否则里面判断会有问题
auto cur=st.top();
res[cur.second]=i-cur.second;
st.pop();
}
st.push(p);
}
return res;
}
};
5.柱状图中的最大矩形
思路是始终维护一个单调递增栈,然后注意,每次右边碰到比栈顶小的,先记录一下当前栈顶的索引,然后弹出(不弹出没法看到左边界,因为左边界本身就需要top取出),然后可以理解为,包容我目前完整整的木板,再左右边界一减,注意当栈是空的时候,左边界取不到,所以你就取个i作为宽度。
哦还要搞个0,作为哨兵,保证递增的时候也可以被处理到
cpp
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
heights.push_back(0);
vector<int> s;
s.assign(heights.begin(), heights.end());
stack<int> st;
for(int i=0;i<heights.size();i++){
while(!st.empty()&&heights[st.top()]>heights[i]){
int cur=st.top();
st.pop();
int left;
if(!st.empty()) left=st.top();//左边界
s[cur]=heights[cur]*(st.empty()?i:i-left-1);
}
st.push(i);
}
return *max_element(s.begin(),s.end());
}
};