20. 有效的括号
描述
Difficulty: 简单
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
提示:
s仅由括号'()[]{}'组成
思路说明:
- 遇到左括号就将匹配的右括号压入栈;
- 遇到右括号则与栈顶元素比较,若不匹配则返回 false。
边界情况提示:
"]"这样的字符串开头就是右括号,栈为空,应返回 false。
Solution
class Solution {
public:
bool isValid(string s) {
stack<char>st;
for(int i = 0; i < s.size(); i++){
if(s[i] != '(' && s[i] != '[' && s[i] != '{'){
if(st.empty()) return false;
else {
char x = st.top(); st.pop();
if(x != s[i]) return false;
}
}
else if(s[i] == '(') st.push(')');
else if(s[i] == '[') st.push(']');
else if(s[i] == '{') st.push('}');
}
return st.empty();
}
};
155. 最小栈
描述
Difficulty: 中等
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack()初始化堆栈对象。void push(int val)将元素val推入堆栈。void pop()删除堆栈顶部的元素。int top()获取堆栈顶部的元素。int getMin()获取堆栈中的最小元素。
示例 1:
输入:
["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.
提示:
pop、top和getMin操作总是在 非空栈 上调用push,pop,top,和getMin最多被调用 次
思路说明:
- 使用两个栈,一个正常存数据,另一个维护当前最小值;
- 压入时如果比最小栈栈顶更小或相等,就同步压入最小栈;
- 弹出时如果正好是最小值,两个栈都弹出。
Solution
class MinStack {
public:
stack<int>st1,st2;
MinStack() {
}
void push(int val) {
st1.push(val);
if(!st2.empty()){
if(st2.top() >= val) st2.push(val);
}
else st2.push(val);
}
void pop() {
if(!st2.empty()){
if(st2.top() == st1.top()) st2.pop();
}
st1.pop();
}
int top() {
return st1.top();
}
int getMin() {
if(!st2.empty()) return st2.top();
return st1.top();
}
};
394. 字符串解码
描述
Difficulty: 中等
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
示例 1:
输入:s = "3[a]2[bc]"
输出:"aaabcbc"
示例 2:
输入:s = "3[a2[c]]"
输出:"accaccacc"
示例 3:
输入:s = "2[abc]3[cd]ef"
输出:"abcabccdcdcdef"
示例 4:
输入:s = "abc3[cd]xyz"
输出:"abccdcdcdxyz"
提示:
s由小写英文字母、数字和方括号'[]'组成s保证是一个 有效 的输入。s中所有整数的取值范围为[1, 300]
思路说明:
- 用两个栈:数字栈和字符串栈;
- 遇到
[时将当前累计字符串入栈; - 遇到
]时拼接重复字符串。
Solution
class Solution {
public:
string decodeString(string s) {
string ss="";
stack<int>st1;
stack<string>st2;
int n = 0;
for(int i = 0; i < s.size(); i++){
if(s[i] >= 'a' && s[i] <= 'z'){
string x = "";
x += s[i];
if(st2.empty()) ss += s[i];
else st2.push(x);
}
else if(s[i] == '['){
st1.push(n); n = 0;
string x = "";
x += s[i];
st2.push(x);
}
else if(s[i] == ']'){
string x = "",y = ""; int m = st1.top(); st1.pop();
while(st2.top() != "["){
x += st2.top(); st2.pop();
}
st2.pop();
while(m--) y += x;
if(st2.empty()) {
reverse(y.begin(), y.end());
ss += y;
}
else st2.push(y);
}
else n = n * 10 + (s[i] - '0');
}
return ss;
}
};
739. 每日温度
描述
Difficulty: 中等
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
示例 1:
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
示例 2:
输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]
示例 3:
输入: temperatures = [30,60,90]
输出: [1,1,0]
提示:
思路说明:
- 使用单调栈(存储索引值,栈内元素保持降序);
- 如果当前温度大于栈顶索引所对应的温度,则弹出并计算间隔。
Solution
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
vector<int>ans(temperatures.size(), 0);
stack<int>st; st.push(0);
for(int i = 1; i < temperatures.size(); i++){
while(!st.empty() && temperatures[i] > temperatures[st.top()]){
ans[st.top()] = i - st.top(); st.pop();
}
st.push(i);
}
return ans;
}
};
84. 柱状图中最大的矩形
描述
Difficulty: 困难
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例 1:
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
示例 2:
输入: heights = [2,4]
输出: 4
提示:
思路说明:
- 先在 heights 数组首尾加 0,可以避免边界特判;
- 用单调递增栈,遇到下降即可确定右边界为
i、注意左边界需要是栈顶左边的下标。 - 知晓左右边界即可进行面积的计算
注意事项:
- 栈中存的是
pair<下标, 高度>; - 弹出栈顶后
宽度 = 当前下标 - 栈顶新 top 的下标 - 1。
Solution
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
stack<pair<int,int>>st; st.push({0,0});
heights.insert(heights.begin(), 0); heights.push_back(0);
int mx = 0;
for(int i = 1; i < heights.size(); i++){
if(heights[i] >= st.top().second){
st.push({i, heights[i]});
continue;
}
while(heights[i] < st.top().second){
int x = st.top().second;st.pop();
mx = max(mx, x * (i - st.top().first - 1));
}
st.push({i, heights[i]});
}
return mx;
}
};