Skip to content

Commit 395c6d5

Browse files
committed
动态规划-42.接雨水-注释
1 parent 24518be commit 395c6d5

File tree

1 file changed

+36
-21
lines changed

1 file changed

+36
-21
lines changed

leetcode_Java/Solution0042.java

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -89,22 +89,31 @@ public int trap(int[] height) {
8989

9090

9191
/*
92-
双指针
92+
双指针:
93+
1、变量含义
94+
leftMax:左边的最大值,它是从左往右遍历找到的
95+
rightMax:右边的最大值,它是从右往左遍历找到的
96+
left:从左往右处理的当前下标
97+
right:从右往左处理的当前下标
98+
2、双指针left、right的作用是 从两端向中间遍历整个数组,记录左右最大值,并计算每个位置的雨水
99+
3、在某个位置i处,它能存的水,取决于它左右两边的最大值中较小的一个,与当前位置的高度差
100+
4、在某个位置i处,它左边最大值一定是leftMax,右边最大值大于等于rightMax
101+
所以如果 leftMax <= rightMax,那么 左边最大值 <= 右边最大值,那么位置i的 左右最大值 较小者就是 leftMax
102+
所以当 leftMax <= rightMax 时,就去处理left下标,反之就去处理right下标
93103
*/
94104
class Solution {
95105
public int trap(int[] height) {
96-
int n = height.length;
97-
int sum = 0;
106+
int left = 0, right = height.length - 1;
98107
int leftMax = 0, rightMax = 0;
99-
int left = 1, right = n - 2;
100-
for (int i = 1; i < n - 1; i++) {
101-
if (height[left - 1] < height[right + 1]) {
102-
leftMax = Math.max(leftMax, height[left - 1]);
103-
sum += (leftMax > height[left]) ? leftMax - height[left] : 0;
108+
int sum = 0;
109+
while (left <= right) {
110+
if (leftMax <= rightMax) {
111+
sum += Math.max(0, leftMax - height[left]);
112+
leftMax = Math.max(leftMax, height[left]);
104113
left++;
105114
} else {
106-
rightMax = Math.max(rightMax, height[right + 1]);
107-
sum += (rightMax > height[right]) ? rightMax - height[right] : 0;
115+
sum += Math.max(0, rightMax - height[right]);
116+
rightMax = Math.max(rightMax, height[right]);
108117
right--;
109118
}
110119
}
@@ -114,26 +123,32 @@ public int trap(int[] height) {
114123

115124

116125
/*
117-
126+
单调递减栈:
127+
1、单调递减栈,height元素作为右柱依次入栈,出现入栈元素(右柱)比栈顶大时,说明在右柱左侧形成了低洼处
128+
2、栈不为空,且当前元素(右柱)比栈顶(右柱的左侧)大,说明形成低洼处了
129+
3、低洼处出栈后,栈如果为空,说明没有左柱,不能接雨水
130+
4、否则,获取低洼处、左柱、右柱的高度,计算雨水。
131+
积攒的水 = 距离 * 高度差
132+
= (右柱位置-左柱位置-1) * (min(右柱高度, 左柱高度)-低洼处高度)
133+
5、循环结算完雨水后,右柱入栈,保证了栈内元素单调递减
118134
*/
119135
class Solution {
120136
public int trap(int[] height) {
121137
int sum = 0;
122-
int index = 0;
123138
Stack<Integer> stack = new Stack<>();
124-
while (index < height.length) {
125-
while (!stack.empty() && height[index] > height[stack.peek()]) {
126-
int outVal = height[stack.peek()];
127-
stack.pop();
139+
for (int right = 0; right < height.length; right++) {
140+
while (!stack.empty() && height[right] > height[stack.peek()]) {
141+
int bottom = stack.pop();
128142
if (stack.empty()) {
129143
break;
130144
}
131-
int distance = index - stack.peek() - 1;
132-
int minVal = Math.min(height[stack.peek()], height[index]);
133-
sum += distance * (minVal - outVal);
145+
int left = stack.peek();
146+
int bottomHeight = height[bottom];
147+
int leftHeight = height[left];
148+
int rightHeight = height[right];
149+
sum += (right - left - 1) * (Math.min(leftHeight, rightHeight) - bottomHeight);
134150
}
135-
stack.push(index);
136-
index++;
151+
stack.push(right);
137152
}
138153
return sum;
139154
}

0 commit comments

Comments
 (0)