Trapping Rain Water

本文详细介绍了如何通过不同的算法解决雨水收集问题,包括使用动态规划、两遍扫描和栈等方法来计算给定地形能捕捉多少雨水。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

For example, 
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.


The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!

Have you been asked this question in an interview?  
方法一: dp
两个for循环求出每个点左右两边的最高bar, 再用一个for 循环求出对于每个点可以的存水量。
该方法还可以优化 将求右边bar 和求最后结果合到一起 
注意:要考虑到 当前的a[i] 比左右两边的bar 高时,不进行操作

public class Solution {
    public int trap(int[] A) {
        if (A == null || A.length == 0) {
            return 0;
        }
        int[] leftBar = new int[A.length];
        leftBar[0] = 0;
        for (int i = 1; i < A.length; i++) {
            leftBar[i] = Math.max(leftBar[i - 1], A[i - 1]);
        }
        int[] rightBar = new int[A.length];
        rightBar[A.length - 1] = 0;
        for (int i = A.length - 2; i > 0; i--) {
            rightBar[i] = Math.max(rightBar[i + 1], A[i + 1]);
        }
        int res = 0;
        for (int i = 1; i < A.length - 1; i++) {
            if (Math.min(leftBar[i], rightBar[i]) > A[i]) {
                res += Math.min(leftBar[i], rightBar[i]) - A[i];
            }
        }
        return res;
    }
}

将第二个和第三个 for 循环合并后:
public class Solution {
    public int trap(int[] A) {
        if (A == null || A.length == 0) {
            return 0;
        }
        int[] leftBar = new int[A.length];
        leftBar[0] = 0;
        for (int i = 1; i < A.length; i++) {
            leftBar[i] = Math.max(leftBar[i - 1], A[i - 1]);
        }
        int right = A[A.length - 1] ;
        int res = 0;
        for (int i = A.length - 2; i > 0; i--) {
            if (Math.min(leftBar[i], right) > A[i]) {
                res += Math.min(leftBar[i], right) - A[i];
            }
            right = Math.max(right, A[i]);
        }
        return res;
    }
}

九章的解法与以上方法有点不同,但是也很好理解:
public class Solution {
    public int trap(int[] A) {
        int sum = 0;
        int max = -1;
        int maxIndex = -1;
        int prev;

        // find the highest bar
        for (int i = 0; i < A.length; i++) {
            if (max < A[i]) {
                max = A[i];
                maxIndex = i;
            }
        }

        // process all bars left to the highest bar
        prev = 0;
        for (int i = 0; i < maxIndex; i++) {
            if (A[i] > prev) {
                sum += (A[i] - prev) * (maxIndex - i);
                prev = A[i];
            }
            sum -= A[i];
        }

        // process all bars right to the highest bar
        prev = 0;
        for (int i = A.length - 1; i > maxIndex; i--) {
            if (A[i] > prev) {
                sum += (A[i] - prev) * (i - maxIndex);
                prev = A[i];
            }
            sum -= A[i];
        }

        return sum;
    }
}


还有一种比较聪明的方法是用stack, 时间复杂度都是 o(n), 但是 只用一次for 循环即可。这种方法 和 Largest Rectangle in Histogram 有点像

public class Solution {
    public int trap(int[] A) {
    	Stack<Integer> pre = new Stack<Integer>();
    	int result = 0;
    	for(int i = 0; i < A.length; i++) {
    	    if(pre.isEmpty() || A[pre.peek()] > A[i]) {
    	        pre.push(i);
    	        continue;
    	    }
    	    int mid = pre.pop();
    	    if(pre.isEmpty()) pre.push(i);
    	    else {
    	        int left = pre.peek();
    	        result += (Math.min(A[left], A[i])-A[mid]) * (i-left-1);
    	        i--;
    	    }
    	}
    	return result;
    }
}


基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明,该项目是个人毕设项目,答辩评审分达到98分,代码都经过调试测试,确保可以运行!欢迎下载使用,可用于小白学习、进阶。该资源主要针对计算机、通信、人工智能、自动化等相关专业的学生、老师或从业者下载使用,亦可作为期末课程设计、课程大作业、毕业设计等。项目整体具有较高的学习借鉴价值!基础能力强的可以在此基础上修改调整,以实现不同的功能。 基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明基于pytorch实现中国交通警察指挥8种手势识别源码+数据集+模型+详细项目说明基于pytorch实现中国交通警察指
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值