[LeetCode]101. Trapping Rain Water收集雨水

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!

Subscribe to see which companies asked this question

解法1:遍历数组,找到局部最小值,方法是如果当前值大于或等于前一个值,或者当前值大于后一个值则跳过。找到了局部最小值后,然后向左找左边的最大值,再向右找右边的最大值,找右边最大值时要注意当其大于左边最大时就停止寻找。然后算出从左边最大值到右边最大值之间能装的水量,之后从右边最大值的位置开始继续找局部最小值,以此类推直到遍历完整个数组。

class Solution {
public:
    int trap(vector<int>& height) {
        int sumTrap = 0, n = height.size(), left = 1, right = 0;
        for (int i = 1; i < n - 1; ++i) {
            if (height[i] >= height[i - 1] || height[i] > height[i + 1]) continue;
            for (left = i - 1; left > 0; --left) {
                if (height[left] >= height[left - 1]) break;
            }
            right = i + 1;
            for (int j = i + 1; j < n; ++j) {
                if (height[j] >= height[right]) {
                    right = j;
                    if (height[right] >= height[left]) break;
                }
            }
            int h = min(height[left], height[right]);
            for (int k = left + 1; k < right; ++k) {
                if (h > height[k]) sumTrap += h - height[k];
            }
            i = right;
        }
        return sumTrap;
    }
};

解法2:对于每一个值,其与另外两个值组成的容器收集的雨水最大量肯定是在其左右两边的最大值作为容器的两个壁的情况下获得的,具体在题目里就是这两个最大值的较小值与当前值的差(当这个最小值大于当前值时,否则收集不到雨水)。使用动态规划,初始化一维数组vector<int> dp(n,0)。然后遍历两遍数组,第一次遍历从左边扫描找出当前位置左边的最大值,并存放到dp中;第二次遍历从右边扫描找出当前位置右边的最大值,然后与dp中保存的左边最大值比较,存下二者之中的较小值,并且将这个值与当前值比较,如果大于当前值,则收集的雨水总量应该加上这个较小值与当前值的差值。

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

解法3:根据上面的雨水收集的分析,任意3个值组成的雨水收集量即是两边的较小值与中间值的差值(如果前者大于后者)。因此可以设置两个指针从两头往中间遍历,这两个指针所指的值即为容器的两个壁。低的壁(较小值)决定了收集雨水的量,因此中间值设为从较小值的后续值,并且算出收集的雨水,直到遇到一个值大于这个较小值,并且更新较小值为当前值。这样只需一趟扫描就可以解决问题。

class Solution {
public:
    int trap(vector<int>& height) {
        int n = height.size(), left = 0, right = n - 1, sum_trap = 0;
        while (left < right) {
            int min_value = min(height[left], height[right]);
            if (height[left] == min_value) {
                ++left;
                while (height[left] < min_value) sum_trap += min_value - height[left++];
            }
            else {
                --right;
                while (height[right] < min_value) sum_trap += min_value - height[right--];
            }
        }
        return sum_trap;
    }
};
时间: 2024-10-19 07:36:47

[LeetCode]101. Trapping Rain Water收集雨水的相关文章

[LintCode] Trapping Rain Water 收集雨水

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. Have you met this question in a real interview? Yes Example Given [0,1,0,2,1,0,1,3,2,1,2,1], return

leetCode 42.Trapping Rain Water(凹槽的雨水) 解题思路和方法

Trapping Rain Water 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

[LeetCode][JavaScript]Trapping Rain Water

Trapping Rain Water 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

Leetcode 407. Trapping Rain Water II

Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevation map, compute the volume of water it is able to trap after raining. Note:Both m and n are less than 110. The height of each unit cell is greater tha

LeetCode 042 Trapping Rain Water

题目要求:Trapping Rain Water 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 elevatio

Leetcode 动态规划 Trapping Rain Water

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie Trapping Rain Water Total Accepted: 14568 Total Submissions: 50810My Submissions Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much wate

【leetcode】Trapping Rain Water

Trapping Rain Water 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

[LeetCode][Java] Trapping Rain Water

题意: 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

LeetCode[Array]: Trapping Rain Water

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 a