题目:
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = [4,2,0,3,2,5]
输出:9
提示:
n == height.length
1 <= n <= 2 * 104
0 <= height[i] <= 105
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/trapping-rain-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
结果:

用栈实际上也只是一个数据进栈,不过不知道为啥耗时又差距。
解题思路:
因为就算用栈,实际上存储的也是一个数据,所以这里用变量的方法说。
topHigh:变量用于存储目前最大的柱子所在下标。
trapSum:用于存储目前为止储水格子数量。
tempSum:用于存储目前位置柱子格子数量。
一、从前往后遍历
本次需要遍历到最后:
如果当前柱子比记录的柱子矮,则将柱子高度所占格子数量增加到tempSum中。
如果当前柱子比记录的柱子高或者相等:
本次出水量sum = (当前下标 - 之前最高柱子下标 - 当前柱子占用格子宽度1) * 之前柱子高度 - 这个之间所有柱子格子数。
因为当前柱子是高于等于之前柱子高度的,因此能最大出水的高度是之前柱子的高度。
二、从后往前遍历
第二次遍历的时候,后面最高柱子就是之前遍历完存储在topHigh的柱子,因此我们只需要遍历到这个柱子就可以停止了。
从后面开始遍历,逻辑和第一遍一样,仅仅是停止循环的位置提前了。
本次出水量sum = (之前最高柱子下标 - 当前下标 - - 当前柱子占用格子宽度1) * 之前柱子高度 - 这个之间所有柱子格子数。
代码:
/* 用变量记录 */
int trap(int* height, int heightSize){
int topHigh = 0;
int trapSum = 0;
int tempSum = 0;
// 从前到最高处位置的出水量计算
for (int i = 1; i < heightSize; i++) {
if (height[i] < height[topHigh]) {
tempSum += height[i];
} else {
int sum = (i - topHigh - 1) * height[topHigh] - tempSum;
trapSum += sum;
tempSum = 0;
topHigh = i;
}
}
// 从后往最高柱子位置的出水量
int rTopHigh = topHigh;
tempSum = 0;
topHigh = heightSize - 1;
for (int i = topHigh - 1; i >= rTopHigh; i--) {
if (height[i] < height[topHigh]) {
tempSum += height[i];
} else {
int sum = (topHigh - i - 1) * height[topHigh] - tempSum;
trapSum += sum;
tempSum = 0;
topHigh = i;
}
}
return trapSum;
}
/*
int trap(int* height, int heightSize){
int *stack = (int *)malloc(sizeof(int) * heightSize);
int top = -1;
int trapSum = 0;
int tempSum = 0;
// 从前到最高处位置的出水量计算
for (int i = 0; i < heightSize; i++) {
if (top == -1) {
stack[++top] = i;
continue;
}
if (height[i] < height[stack[top]]) {
tempSum += height[i];
} else {
int sum = (i - stack[top] - 1) * height[stack[top]] - tempSum;
trapSum += sum;
tempSum = 0;
top = 0;
stack[top] = i;
}
}
// 从后往最高柱子位置的出水量
int topHigh = stack[top];
tempSum = 0;
top = -1;
for (int i = heightSize - 1; i >= topHigh; i--) {
if (top == -1) {
stack[++top] = i;
continue;
}
if (height[i] < height[stack[top]]) {
tempSum += height[i];
} else {
int sum = (stack[top] - i - 1) * height[stack[top]] - tempSum;
trapSum += sum;
tempSum = 0;
top = 0;
stack[top] = i;
}
}
return trapSum;
}
*/
本文介绍了LeetCode第42题《接雨水》的解题思路,通过从前往后和从后往前两次遍历数组,计算能接收到的雨水量。文中详细解释了如何利用变量记录最高柱子的下标和储水格子的数量,以及如何计算出水量。代码实现简洁明了,适合C语言初学者学习。
1431

被折叠的 条评论
为什么被折叠?



