LeetCode系列之【42. 接雨水】C++ 每天一道leetcode!

目录(快速导航)

题目描述

视频讲解 https://www.bilibili.com/video/av66851964/

思路

代码


题目描述:

题目链接:https://leetcode-cn.com/problems/trapping-rain-water/submissions/

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 

示例:
输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6

视频讲解

https://www.bilibili.com/video/av66851964/


思路:

暴力法:

主要的想法是我们遍历整个数组,然后我们查看每一个位置上能接多少雨水,让后进行累加即可。那么对于位置i,其可以接到的雨水为:令i左边的最高墙(包括i)为max_left[i],i右边的最高墙(包括i)为max_right[i],之后选择其中的较小者,就获得了在i位置上桶的高度,再减去桶底的高度height[i],就为该位置上能接的雨水量。

动态编程:

也就是因为,暴力在计算每一个位置i的max_left[i]和max_right[i]时,需要重复遍历数组,那么我们只需要找一个地方给他存储下来,那么总的对于max_left数组和max_right我们分别遍历一次数组即可。

双指针:

这个就比较有意思,我们从首位两端分别前进,左边为left,右边为right。我们假想中间的部分我们不知道,我们只知道当前已经在两端看到过的元素,那么我们从两端出发,选择两端中小的值,作为桶高,再时刻保持更新max_left和max_right。如果桶高>=max_left,那么更新max_left,否则累加雨水量到ans即可。


代码:

版本一:动态编程

class Solution {
public:
    int trap(vector& height) {
        if (height.empty()) return 0;
        int size = height.size();
        vector max_left, max_right(size);
        // 设置max_left
        max_left.push_back(height[0]);
        for (int i = 1;i < size;i++) {
            max_left.push_back(max(height[i], max_left[i - 1]));
        }
        // 设置max_right
        max_right[size - 1] = height[size - 1];
        for (int i = size - 2;i >= 0;i--) {
            max_right[i] = max(height[i], max_right[i + 1]);
        }
        // 得到雨水量
        int ans = 0;
        for (int i = 0;i < size;i++) {
            ans += min(max_left[i], max_right[i]) - height[i];
        }
        return ans;
    }
};

版本二:双指针

class Solution {
public:
    int trap(vector& height) {
        int left = 0, right = height.size() - 1, max_left = 0, max_right = 0, ans = 0;
        while (left < right) {
            // 左边小 看左边
            if (height[left] < height[right]) {
                height[left] >= max_left ? (max_left = height[left]) : (ans += max_left - height[left]);
                left++;
            }
            // 右边小
            else {
                height[right] >= max_right ? (max_right = height[right]) : (ans += max_right - height[right]);
                right--;
            }
        }
        return ans;
    }
};

一起加油!!刷题!!

你可能感兴趣的:(leetcode)