42.接雨水
solution
单调栈
public class Solution {
public int Trap(int[] height) {
int result = 0;
Stack<int> st = new Stack<int>();
for(int i = 0; i < height.Length; i ++)
{
while(st.Count > 0 && height[st.Peek()] < height[i])
{
int mid = st.Pop();
if(st.Count > 0)
{
int left = st.Peek();
result += (Math.Min(height[left], height[i]) - height[mid]) * (i - left - 1);
}
}
st.Push(i);
}
return result;
}
}
双指针
public class Solution {
public int Trap(int[] height) {
if (height == null || height.Length == 0) {
return 0;
}
int left = 0, right = height.Length - 1;
int leftMax = 0, rightMax = 0;
int result = 0;
while (left < right) {
// 如果左边的高度小于右边的高度,处理左边
if (height[left] < height[right]) {
if (height[left] >= leftMax) {
leftMax = height[left]; // 更新左边最大高度
} else {
result += leftMax - height[left]; // 当前高度小于最大高度,计算雨水
}
left++;
}
// 如果右边的高度小于等于左边的高度,处理右边
else {
if (height[right] >= rightMax) {
rightMax = height[right]; // 更新右边最大高度
} else {
result += rightMax - height[right]; // 当前高度小于最大高度,计算雨水
}
right--;
}
}
return result;
}
}
summary
84.柱状图中最大的矩形
题目:84. 柱状图中最大的矩形 - 力扣(LeetCode)
题解:代码随想录 (programmercarl.com)
找最大矩形的思路比接雨水稍微绕点
solution
public class Solution {
public int LargestRectangleArea(int[] heights) {
int result = 0;
Stack<int> st = new Stack<int>();
for(int i = 0; i < heights.Length; i ++)
{
while(st.Count > 0 && heights[i] < heights[st.Peek()])
{
int mid = st.Pop();
int width = st.Count == 0 ? i : i - st.Peek() - 1;
int area = heights[mid] * width;
result = Math.Max(result, area);
}
st.Push(i);
}
while(st.Count > 0)
{
int mid = st.Pop();
int area = heights[mid] * (st.Count == 0 ? heights.Length : heights.Length - st.Peek() - 1);
result = Math.Max(result, area);
}
return result;
}
}
summary
建议算面积不要一步到位,清晰表达每个数值,重点是矩形宽度
遍历时:
为栈底时:i
不为栈底时:i - st.Peek() - 1
遍历外:
为栈底时:heights.Length
不为栈底时:height.Length - st.Peek() - 1
但本质上,都是左边界 - 右边界 -1