42.trapping-rain-water

      以前在听算法课的时候,有一个人说过这样一句话,凡是那道题没有思路的9成要用动态规划,当然可能说的有点绝对,但是不无道理,就是说,一般的题目我们遇到后能立即想到思路,哪怕是那种很麻烦的,但是动态规划往往是麻烦的也不一定能想出来。而动态规划的难度也确实比较大,其灵活性很高,他不同于字符串,数组,排序这种的某一类问题,他是一种思想,渗透到各种各样的问题的当中,而leetcode有关动归的问题还不在少数,比较全面。

        题目的大致意思是,给定一个一维数组,每个数字表示对应位置的地基高度,类似于地面的凹凸不平状态,不同的是,这个题目中要求的维度是二维,假设在下雨的时候,凹进去的地面会存入一定量的雨水,存入雨水的多少取决于左右两边最大高度中最小的那一个与该位置的高度差,类似于木桶理论,比如有一个地面是 4 3 5,那么它的最大积水量是 min(5, 4)-3 = 1。

        基于以上的理解,我们就可以使用动态规划的思路,将每一个位置点左侧的最大高度存起来,然后将每个位置点右侧的最大高度存起来,这样,该位置的最大存水量为min(maxleft[i], maxright[i])-height[i] 得到,最后将所有位置相加即可,为了提高空间复杂度方面的性能,我们只需要将所有位置对应的左侧最大高度存在一个数组中,然后每算出一个右侧最大高度,就将该位置对应的存水量算出来,接着进行下一位的计算。

根据以上的思路,下面是AC代码:

class Solution {
public:
    int trap(vector<int>& height) {
        vector<int> dp(height.size(), 0);
        int maxleft = 0;
        for (int i=0; i<height.size(); ++i) {
            dp[i] = maxleft;
            maxleft = max(height[i], maxleft);
        }
        int maxright = 0, res = 0;
        for (int i=height.size()-1; i>=0; --i) {
            dp[i] = min(dp[i], maxright);
            maxright = max(maxright, height[i]);
            if (dp[i]-height[i] > 0) {
                res += (dp[i]-height[i]);
            }
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_29592167/article/details/83111685