leetcode42.接雨水——学习笔记

题目:力扣https://leetcode-cn.com/problems/trapping-rain-water/

class Solution {
    public int trap(int[] height) {
        int len = height.length;
        int[] leftMax = new int[len];
        int[] rightMax = new int[len];
        int top = 0;
        int sum = 0;
        for(int i=0;i<len;i++){
            if(height[i]>top){
                top = height[i];
            }
            leftMax[i] = top;
        }
        top = 0;
        for(int i=len-1;i>=0;i--){
            if(height[i]>top){
                top = height[i];
            }
            rightMax[i] = top;            
        }
        for(int i=0;i<len;i++){
            sum += (Math.min(leftMax[i],rightMax[i])-height[i]);
        }
        return sum;
    }
}

思路:动态规划,有时候觉得难以理解,但是真正理解之后,就会觉得动态规划其实并没有想象中那么难。 动态规划的四个步骤:

(1)将原问题分解为子问题——将求“接雨水量”的问题转化为 从左往右求对应位置最大值(leftMax) 和 从右往左求对应位置最大值(rightMax)两个子问题。

(2)确定状态——每个位置可以蓄水的量称为该位置的“状态”。

(3)确定一些初始状态(边界状态)的值——每个位置中leftMax和rightMax的较小值与该位置柱子高度hight的差 为初始状态的值。

(4)确定状态转移方程——将每个位置可以蓄水的量求和的公式为该题状态转移方程(sum += (Math.min(leftMax[i],rightMax[i])-height[i]);)。

⚠能用动规解决的问题的特点:1) 问题具有最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质。2) 无后效性。当前的若干个状态值一旦确定,则此后过程的演变就只和这若干个状态的值有关,和之前是采取哪种手段或经过哪条路径演变到当前的这若干个状态,没有关系。

1.准备阶段。声明变量len表示hight[]数组的长度;提前声明好leftMax[]和rightMax[]两个数组,后续分别用于存储从左至右数遍历的各个位置对应的最大值和从右往左数遍历的各个位置对应的最大值;声明一个top,是用于记录当前位置最大值,默认值为0;sum是每个位置蓄水量的总和,默认值为0。

int len = height.length;
int[] leftMax = new int[len];
int[] rightMax = new int[len];
int top = 0;
int sum = 0;

2.从左往右遍历,将各位置对应的最大值填入数组中。

for(int i=0;i<len;i++){
    if(height[i]>top){
        top = height[i];
    }
    leftMax[i] = top;
}

3.重置top的值为0。从右往左遍历,将各位置对应的最大值填入数组中。

top = 0;
for(int i=len-1;i>=0;i--){
    if(height[i]>top){
        top = height[i];
    }
    rightMax[i] = top;
}

4.遍历height[]数组,根据公式求出每个位置可以蓄水的量,再将其求和得到sum。

for(int i=0;i<len;i++){
    sum += (Math.min(leftMax[i],rightMax[i])-height[i]);
}

5.当所有位置可蓄水量都加起来之后,sum就是题目所求的答案,返回即可。

return sum;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hokachi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值