每日一题:直方图水量

leetcode每日一题 直方图的水量


直方图的水量
)

自己的想法

每个水池一定是先发生递减,后发生递增的
所以用一个up数组记录数字的变化趋势

对于水池存在二种情况:
1、高地突出,拦截水流
2、水流从高处流下,但是出现了一个小突起,这个小突起对于后面都是高

下面展示一些 内联代码片

public int trap(int[] height) {//有漏洞,做的很不好
//水池一定是被先递减,后递增包围着的
if(height==null||height.length==0){
    return 0;
}
       int length = height.length;
        int[] up = new int[length];
        int[] max1 = new int[length];
        Arrays.fill(up, -1);
       // Arrays.fill(down, -1);

        for (int i = 1; i < length; i++) {
            if (height[i] >= height[i - 1]) {
                up[i] = i;
            }
        }
        max1[length-1]=height[length-1];
        for(int i=length-2;i>=0;i--){
            max1[i]=Math.max(height[i],max1[i+1]);
        }

        //遍历up数组
        boolean up1 = false;
        boolean down1 = false;
        int maxPosition = -1;
        int minPosition = -1;
        int res = 0;
        for (int i = 1; i < length; i++) {
            if (up[i] != -1 && down1) {
                //说明有递增,且前面有递减,找到最大的递增

                minPosition = i;
                up1 = true;
            } else if (up[i] == -1 && i != 0) {
                //说明递减
                if (!down1) {
                    maxPosition = i - 1;
                }
                down1 = true;
            }
            if (up1 && down1 && (i == length - 1 || height[minPosition]>=height[maxPosition]||height[minPosition]==max1[minPosition])) {
                up1 = false;
                down1 = false;
                int max = Math.min(height[maxPosition], height[minPosition]);
                for (int h = maxPosition + 1; h < minPosition; h++) {
                    int num = max - height[h];
                    if (num > 0) {
                        res += num;
                    }
                }
            }
        }
        return res;
        }

题解

动态规划,先前向遍历记录leftMax,然后后向遍历记录rightMax,最后计算重复

 if(height==null||height.length==0){
            return 0;
        }
          //利用动态规划做
        int len=height.length;
        int[] leftMax=new int[len];
        int[] rightMax=new int[len];

        //正向遍历:包括自身,左边最高
        leftMax[0]=height[0];
        rightMax[len-1]=height[len-1];
        for(int i=1;i<len;i++){
            leftMax[i]=Math.max(leftMax[i-1],height[i]);
        }
        //反向遍历,包括自身,右边最高
        for(int i=len-2;i>=0;i--){
            rightMax[i]=Math.max(rightMax[i+1],height[i]);
        }
        int res=0;
        for(int i=0;i<len;i++){
            res+=Math.min(leftMax[i],rightMax[i])-height[i];
        }
        return  res;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值