牛客网top101(接雨水问题)

接雨水问题

在这里插入图片描述
在这里插入图片描述
思路:

我们都知道水桶的短板问题,控制水桶水量的是最短的一条板子。这道题也是类似,我们可以将整个图看成一个水桶,两边就是水桶的板,中间比较低的部分就是水桶的底,由较短的边控制水桶的最高水量。 但是水桶中可能出现更高的边,比如上图第四列,它比水桶边还要高,那这种情况下它是不是将一个水桶分割成了两个水桶,而中间的那条边就是两个水桶的边。

有了这个思想,解决这道题就容易了,因为我们这里的水桶有两个边,因此可以考虑使用对撞双指针往中间靠。

具体做法:

  • step 1:检查数组是否为空的特殊情况
  • step 2:准备双指针,分别指向数组首尾元素,代表最初的两个边界
  • step 3:指针往中间遍历,遇到更低柱子就是底,用较短的边界减去底就是这一列的接水量,遇到更高的柱子就是新的边界,更新边界大小。

图示:

在这里插入图片描述

import java.util.*;
public class Solution {
    public long maxWater (int[] arr) {
        //排除空数组
        if(arr.length == 0) 
            return 0;
        long res = 0;
        //左右双指针
        int left = 0; 
        int right = arr.length - 1; 
        //中间区域的边界高度
        int maxL = 0; 
        int maxR = 0;
        //直到左右指针相遇
        while(left < right){ 
            //每次维护往中间的最大边界
            maxL = Math.max(maxL, arr[left]); 
            maxR = Math.max(maxR, arr[right]);
            //较短的边界确定该格子的水量
            if(maxR > maxL) 
                res += maxL - arr[left++]; 
            else
                res += maxR - arr[right--];
        }
        return res;
    }
}

在 C 语言中,雨水问题通常是一个经典的二维数组(矩阵)遍历和动态规划问题。该问题是这样的:给定一个 n x n 的矩阵,表示一个屋顶的轮廓,每行每列都是从左到右递增或递减的。你需要计算从每个单元格开始,沿上、下、左、右四个方向可以收集到的最大雨水量。 下面是一个简单的 C 语言函数示例,使用嵌套循环和临时变量来解决这个问题: ```c #include <stdio.h> int maxRainwater(int matrix[n][n], int m) { int i, j, max = 0; for (i = 0; i < m; i++) { // 遍历每一行 for (j = 0; j < m; j++) { // 内层循环遍历每一列 if (matrix[i][j] > 0) { // 如果当前位置有水 int left = 0, right = 0, top = 0, bottom = 0; if (j > 0 && matrix[i][j - 1] > 0) // 左侧是否有水 top = matrix[i][j] - matrix[i][j - 1]; else top = matrix[i][j]; if (j < m - 1 && matrix[i][j + 1] > 0) // 右侧是否有水 bottom = matrix[i][j + 1] - matrix[i][j]; else bottom = matrix[i][j]; if (i > 0 && matrix[i - 1][j] > 0) // 上方是否有水 left = matrix[i - 1][j] - matrix[i][j]; else left = matrix[i][j]; if (i < m - 1 && matrix[i + 1][j] > 0) // 下方是否有水 right = matrix[i + 1][j] - matrix[i][j]; else right = matrix[i][j]; max = ((max > top) ? max : top); // 更新最大值 max = ((max > bottom) ? max : bottom); max = ((max > left) ? max : left); max = ((max > right) ? max : right); } } } return max; } // 示例 int main() { int matrix[3][3] = {{0, 1, 0}, {1, 0, 1}, {0, 1, 0}}; printf("Maximum rainwater that can be collected: %d\n", maxRainwater(matrix, 3)); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值