给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。用C语言写出代码
时间: 2024-09-06 14:07:37 浏览: 44
在C语言中,我们可以使用动态规划的思想来解决这个问题。这个经典的题目叫做“最大宽度水桶”,可以使用一个数组`res`来保存每一段连续区域的最大高度,然后遍历整个数组,更新结果。
首先,我们需要定义一个函数`maxWater`,接受两个指针`left`和`right`分别指向当前检查区间的开始和结束位置,以及数组`heights`作为输入:
```c
#include <stdio.h>
int maxWater(int heights[], int n) {
if (n <= 0) return 0; // 如果没有柱子,无法积水
int *left = heights;
int *right = heights + n - 1;
// 初始化结果数组 res,所有位置初始值设为 0
int *res = malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
res[i] = 0;
}
// 从左到右遍历,计算最大雨水量
while (left < right) {
// 如果左侧柱子比右侧高,则雨水从左侧柱子开始收集
if (*left < *right) {
res[left[0]] += min(*left, right[0] - left[0]);
left++;
}
// 否则,雨水从右侧柱子开始收集
else {
res[right[0] - 1] += min(*right, right[0] - left[0]);
right--;
}
}
// 最终结果即为 res 数组中的最大值
int maxRain = 0;
for (int i = 0; i < n; i++) {
maxRain = max(maxRain, res[i]);
}
free(res); // 释放内存
return maxRain;
}
// 主函数测试
int main() {
int heights[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
int n = sizeof(heights) / sizeof(heights[0]);
printf("最多能接的雨水量: %d\n", maxWater(heights, n));
return 0;
}
```
在这个代码中,`min` 函数用于找出两个数值中的最小值。这个算法的时间复杂度为 O(n),其中 n 是柱子的数量,因为需要遍历一次数组。
阅读全文