一、LeetCode155最小栈
题目描述:
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack() 初始化堆栈对象。
void push(int val) 将元素val推入堆栈。
void pop() 删除堆栈顶部的元素。
int top() 获取堆栈顶部的元素。
int getMin() 获取堆栈中的最小元素。
示例:
输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,0,-2]
解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
思路1:
建两个栈;
一个a负责正常的入栈和出栈;
一个b负责存储最小值;
在入栈的时候,a直接入栈,b如果当前值小于等于b的栈顶元素,就入栈;
在出栈的时候,a直接出栈,b如果栈顶元素和a的出栈元素相等,就出栈。
class MinStack {
public:
stack<int> s; //正常栈
stack<int>min; //最小值的栈
public:
MinStack() {
}
void push(int val) {
s.push(val); //正常的直接入栈
if(min.size()==0||val<=min.top())min.push(val);//最小值栈若为空或栈顶元素大于当前值,入栈
}
void pop() {
if(s.top()==min.top())min.pop();//如果正常栈的出栈元素等于最小值栈的栈顶元素,最小值栈出栈
s.pop(); //正常的直接出栈
}
int top() {
return s.top(); //返回正常栈的栈顶
}
int getMin() {
return min.top(); //返回最小值栈的栈顶
}
};
思路2:
建一个栈和一个int变量min
栈用来正常的入栈和出栈;
min用来存储最小值;
入栈时,若入栈元素小于等于min,将min入栈后再将新值入栈,更新min;
出栈时,若出栈元素等于min,将栈顶元素出栈,min等于新的栈顶元素,将栈顶元素再次出栈。
class MinStack {
public:
stack<int> s; //正常栈
int min=INT_MAX; //最小值
public:
MinStack() {
}
void push(int val) {
if(val<=min) //当前值小于最小值
{
s.push(min);//将最小值入栈
min=val; //更新最小值
}
s.push(val); //将当前值入栈
}
void pop() {
if(s.top()==min) //栈顶元素等于最小值
{
s.pop(); //出栈
min=s.top(); //min等于新的栈顶元素
}
s.pop(); //将之前存储的最小值出栈
}
int top() {
return s.top();
}
int getMin() {
return min;
}
};
二、LeetCode20有效的括号
题目描述:
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
示例:
输入:s = "()[]{}" 输出:true
思路:
创建一个栈,
如果是左边括号,就入栈;
如果是右边括号,就判断该右边是否与栈顶左边匹配,
如果匹配,就出栈;
如果不匹配,就返回false;
所有的都遍历之后,判断栈中是否还有元素,
如果有,就返回false;
如果没有,就返回true。
class Solution {
public:
bool isValid(string s) {
stack<char>ss; //辅助栈
for(int a=0;a<s.size();a++)
{
if(s[a]=='('||s[a]=='['||s[a]=='{')ss.push(s[a]);//左边入栈
else if(ss.empty())return false; //不是左边且栈为空,返回f
else if(
(s[a]==')'&&ss.top()=='(')
||(s[a]==']'&&ss.top()=='[')
||(s[a]=='}'&&ss.top()=='{'))ss.pop(); //是右边且和栈顶元素匹配,出栈
else return false; //不匹配,返回f
}
if(ss.empty())return true; //全部匹配,返回t
return false; //站内有剩余,返回f
}
};
三、LeetCode739每日温度
题目描述:
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
示例:
输入: temperatures=[73,74,75,71,69,72,76,73] 输出: [1,1,4,2,1,1,0,0]
思路:
创建一个栈(从栈底到栈顶单调递减),一个用于返回的数组v
遍历数组,
如果栈是空或当前值小于栈顶元素,当前值的下边入栈;
如果当前值大于栈顶元素,v[栈顶]等于当前值和栈顶值的差,出栈,继续比较当前值和新栈顶值。
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
vector<int>v(temperatures.size(),0); //用于返回的数组
stack<int>s; //单调栈
for(int a=0;a<temperatures.size();a++)
{
while(!s.empty()&&temperatures[a]>temperatures[s.top()])//当前值大于栈顶值
{
v[s.top()]=a-s.top(); //记录差值
s.pop(); //出栈
}
s.push(a); //当前值下标入栈
}
return v;
}
};