42. 接雨水
题目链接:
力扣题目链接
思路:单调栈使用单调栈栈由栈顶向栈底递增,这样与之前单调栈相同也就是遇到大于当前栈顶就进行计算pop,核心代码在下方,只计算当前栈顶左右两个高度相对较小一方来计算高度,要减去挡圈栈顶的高度,乘以左右来两侧长度,因为可能有两个高度一样的入栈,不必担心因为这样的话计算面积的高度为零,这样会继续while循环。
while (!stack.isEmpty() && height[i] > height[stack.peek()]) {
int h = height[stack.pop()];
if (stack.isEmpty()) break; // 如果栈为空,则没有左边的边界
int width = i - stack.peek() - 1;
int minHeight = Math.min(height[stack.peek()], height[i]);
sum += (minHeight - h) * width;
}
双指针方法左右两个指针,然后记录左右两侧最大值while循环比较左右两个指针那个小哪边小就修改哪边,如果当前左/右指针小于左/右的最大值就计算当前面积,如果大于就更新最大值以此类推直到左侧指针大于等于右侧指针结束。
class Solution {
public int trap(int[] height) {
if (height == null || height.length == 0) return 0;
int left = 0, right = height.length - 1;
int Max_l = 0, Max_r = 0;
int sum = 0;
while (left < right) {
if (height[left] < height[right]) {
if (height[left] >= Max_l) {
Max_l = height[left]; // 更新左边最大值
} else {
sum += Max_l - height[left]; // 计算水量
}
left++; // 左指针向右移动
} else {
if (height[right] >= Max_r) {
Max_r = height[right]; // 更新右边最大值
} else {
sum += Max_r - height[right]; // 计算水量
}
right--; // 右指针向左移动
}
}
return sum;
}
}
84.柱状图中最大的矩形
题目链接:
力扣题目链接
思路:这个和之前的“
42. 接雨水
”类似,但是单调栈是递增的而且面积计算的是柱状的面积,同时数组两端要各加一个0,需要避免整个排序就是递减和数组中最小的那个柱无法计算的情况。
class Solution {
public int largestRectangleArea(int[] heights) {
Stack<Integer> stack = new Stack<>();
int res = 0;
int[] height = new int[heights.length+2];
height[0]=0;
int j=1;
for(int he : heights){
height[j]=he;
j++;
}
height[j]=0;
for (int i = 0; i < height.length; i++) {
while (!stack.isEmpty() && height[i] < height[stack.peek()]) {
int l = stack.pop();
int h = height[l];
int width = i - stack.peek() - 1;
res = Math.max(res,h* width);
}
stack.push(i);
}
return res;
}
}
时间:2.5h