leetcode--trapping_rain_water

33 篇文章 0 订阅
27 篇文章 0 订阅

题意: 给定n个由非负整数表示的正视图,每一个块的宽度是1,计算可以放多少水。
举例: 给定一个数组[0, 1, 0, 2, 1, 0 , 1, 3, 2, 1, 2, 1],返回6,图示如下:

分析: 本题的标注是栈,我一开始也是往栈的方向去想,虽然可以实现,但是比较繁琐。做完之后参考其他算法大牛的做法,发现可以使用时间复杂度是O(n),空间复杂度是O(1)的方法,更加高效。算法思想是:先遍历一趟数组,找到最高的,然后将数组从最高处分成左右两部分,分别计算左边的和右边的容量,左边的可以从起始位置向最高位置遍历,右边的从末端位置向最高处遍历,经过这两趟遍历即可求得最终解。算法思路比较清晰,也容易理解,需要记下来这种解题方法。

代码
先贴上我自己的代码吧,虽然比较复杂…

import java.util.Stack;
public class Solution {
    public int trap(int[] A) {
        Stack<Integer> stack = new Stack<>();
        if(A == null || A.length == 0){
            return 0;
        }else{
            stack.push(A[0]);
            int height = A[0];
            int result = 0;
            for(int i = 1; i < A.length; i++){
                if(A[i] < height){       //如果当前值小于height,就加入栈当中
                    stack.push(A[i]);
                }else{                  //如果当前值大于等于height,那就说明可以存水
                    while(!stack.isEmpty()){
                        result += height - stack.pop(); //可以盛放多少水等于当前的高度height减去小方块的高度
                    }
                    stack.push(A[i]);  
                    height = A[i];  //修改高度
                }
            }
            height = stack.pop();   //到最后都没有比当前height更高以后,从栈顶向栈底走逐步求可容纳的水量
            while(!stack.isEmpty()){
                int temp = stack.pop();
                if(temp <= height) result += height - temp;
                else{
                    height = temp;
                }
            }
            return result;
        }

    }
}

源程序下载

更高效的一个算法实现
虽然是C++版本的,不过基本和java的一样,除了定义类和方法时略有不同。

class Solution {
public:
    int trap(int heights[], int n) {
        int maxhigh=0;
        int left=0,right=0;
        for(int i=0;i<n;i++)//找到最大值的下标
        {
            if(heights[i]>heights[maxhigh])
                maxhigh=i;
        }
        int sum=0;
        for(int i=0;i<maxhigh;i++)//计算左边的容量
        {
            if(heights[i]<left)
               sum+=(left-heights[i]);
            else
               left=heights[i];
        }

        for(int j=n-1;j>maxhigh;j--)//计算右边的容量
        {
            if(heights[j]<right)
               sum+=(right-heights[j]);
            else
               right=heights[j];
        }
        return sum;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值