力扣 42. 接雨水

98 阅读1分钟

🔗 leetcode.cn/problems/tr…

题目

  • 给出一个数组表示宽度为 1, 高度为 num[i] 的柱子,求下雨后,这些柱子能接住多少雨水。据说是字节经典面试题

思路

  • 自己朴素的想法 solution1 是:

    • 下标从小到大,找到柱子高度从小到大的递增序列,计算这中间可以接的雨水;
    • 下标从大到上述找到的最高柱子的下标,同样找递增序列,计算中间可以接的雨水;
  • 题目分类是 two-pointer,按照该解法 solution 2 的思路是:

    • 分别看柱子的两头,分别记录 left_max 和 right_max
    • 若左边的柱子比右边的柱子高,代表右边的柱子高度可以尝试接雨水,right_max - height right,变动 right pointer
    • 反义依然,若相等,随便变动一个 pointer

代码

class Solution {
public:
    int solution1(vector<int>& height) {
        int ans = 0;
        vector<int> asc;
        // asc
        asc.push_back(0);
        int n = height.size();
        for (int i = 1; i < n; i++) {
            if (height[asc.back()] <= height[i]) {
                asc.push_back(i);
            }
        }
        int end = asc.back();
        int h = height[0];
        for (int i = 1; i < asc.size(); i++) {
            for (int j = asc[i - 1]; j < asc[i]; j++) {
                ans += (h - height[j]);
            }
            h = height[asc[i]];
        }

        // desc
        asc.clear();
        asc.push_back(height.size() - 1);
        for (int i = n - 2; i >= end; i--) {
            if (height[asc.back()] <= height[i]) {
                asc.push_back(i);
            }
        }
        h = height.back();
        for (int i = 1; i < asc.size(); i++) {
            for (int j = asc[i - 1]; j > asc[i]; j--) {
                ans += (h - height[j]);
            }
            h = height[asc[i]];
        }

        return ans;
    }
    
    int solution2(vector<int>& height) {
        int l = 0, r = height.size() - 1, l_max = height[0], r_max = height.back();
        int ans = 0;
        while (l < r) {
            while (l < r && height[l] <= height[r]) {
                l_max = max(l_max, height[l]);
                ans += l_max - height[l];
                l++;

            }
            while (l < r && height[l] > height[r]) {
                r_max = max(r_max, height[r]);
                ans += r_max - height[r];
                r--;
            }
        }
        return ans;

    }
    int trap(vector<int>& height) {
        //return solution1(height);
        return solution2(height);
        
    }
};