739.每日温度 题目:
思路:
①暴力法:两个循环
②单调栈:用栈来存放数组下标
当栈为空或当前温度小于等于栈顶索引对应的温度时,入栈
否则,出栈,日期则等于i - stack.pop()
代码:
class Solution {
public int[] dailyTemperatures(int[] T) {
Stack<Integer> stack = new Stack<Integer>();
int len = T.length;
int[] ans = new int[len];
for(int i = 0;i < len;i++){
while(!stack.isEmpty() && T[i] > T[stack.peek()]){
ans[stack.peek()] = i - stack.peek();
stack.pop();
}
stack.push(i);
}
return ans;
}
}
复杂度分析:
时间复杂度:O(n)
空间复杂度:O(n)
42.接雨水 题目
思路:
维护一个递减的栈
①遍历每一个高度
②栈不为空 && 当前高度 > 栈顶高度,弹出栈顶
③当前高度 == 栈顶高度时,弹出栈顶
④栈不为空时(说明两边均有界),计算当前块的行容量
⑤压栈
代码:
class Solution {
public int trap(int[] height) {
Stack<Integer> stack= new Stack<Integer>();
int len = height.length;
int ans = 0;
for(int i = 0;i < len;i++){
int right = i;
while(!stack.isEmpty() && height[i] > height[stack.peek()]){//栈不为空&&当前高度>栈顶高度,弹出栈顶
int cur_index = stack.pop();
while(!stack.isEmpty() && height[cur_index] == height[stack.peek()])//当前高度 == 栈顶高度,弹出栈顶,一个不留
stack.pop();
if(!stack.isEmpty()){
int left = stack.peek();
ans += (Math.min(height[left],height[right]) - height[cur_index])*(right - left - 1);
}
}
stack.push(i);
}
return ans;
}
}
复杂度分析:
时间复杂度:O(n)
空间复杂度:O(n)
84.柱状图中最大的矩形 题目
思路:
①要找到包含第 i 个矩形的最大面积,就要分别找到小于第 i 个位置高度的左右两边高度,维护一个递增的单调栈,来确定左边界,右边界就是当前遍历到的矩形
②Tips:在这组矩形的首尾各自加一个高度为0的矩形
左边的0是为了保证宽度计算不遗漏
右边的0是为了保证每个位置的最大矩阵面积都可以得到计算
代码:
class Solution {
public int largestRectangleArea(int[] heights) {
Stack<Integer> stack = new Stack<Integer>();
int right,left,cur_height;
int max_s = 0;
int len = heights.length;
int[] new_heights = new int[len + 2];
for(int i = 1; i < len+1;i++){
new_heights[i] = heights[i-1];
}//首尾增加两个高度为0的矩形,尾部加0是为了保证每个位置的最大矩形面积都得到计算
for(int i = 0;i < len+2;i++){
while(!stack.isEmpty() && new_heights[stack.peek()] > new_heights[i]){//维护一个递增栈,高度相等的不再加入
right = i;//确定右边界
cur_height = new_heights[stack.peek()];
stack.pop();
left = stack.peek();//确定左边界,因为数组最左边为0,因此不担心栈为空
max_s = Math.max(max_s,cur_height*(right-left-1));
}
stack.push(i);
}
return max_s;
}
}
复杂度分析:
时间复杂度:O(n)
空间复杂度:O(n)