LC.42 | 接雨水 | 栈 | 单调栈

输入: 给定 n 个非负整数数组,表示宽为 1 的柱子的高度。

要求: 计算下雨之后,这些柱子能接住多少雨水。

输出: 一个整数,表示能接住的雨水总量。


思路1:核心是为每个柱子寻找左右更高的边界,并计算两者间的储水量。通过遍历数组,用栈定位左边界,当找到右边界后计算中间柱子的水量并累加。为防止重复计算,将中间柱子的高度更新为边界高度,从而避免后续重复统计。(核心就在于不断修改柱子高度,防止重复计算,但是很绕,远不如思路2简洁明了。)


思路2:计算接水量,只需要找到每个位置上方能容纳水的最小高度限制。这个限制由该位置的左侧最高墙右侧最高墙中较低的一个决定。

因此:

  1. 预计算左侧最高墙: 遍历数组,用一个辅助数组记录每个位置向左看,遇到的最高柱子高度。

  2. 预计算右侧最高墙: 反向遍历数组,用另一个辅助数组记录每个位置向右看,遇到的最高柱子高度。

  3. 计算并累加水量: 再次遍历数组,对于每个位置,取其左侧最高墙和右侧最高墙中的较小值,然后减去当前柱子的高度。这个差值就是当前位置上方接到的雨水量,将所有位置的雨水量累加即可得到最终答案。


复杂度:

        时间复杂度:O(n)

        空间复杂度:O(n)


// class Solution {
// public:
//     int trap(vector<int>& height) {
//         int ans = 0;
//         stack<int> tmp;
//         int sum = 0;
//         for (int i = 0; i < height.size(); i++) {
//             if (tmp.empty()) {
//                 if (height[i] == 0) {
//                     continue;
//                 }
//                 tmp.push(i);
//             }
//             else if (height[i] >= height[tmp.top()]) {
//                 while (tmp.size() > 1 && height[i] > height[tmp.top()]) {
//                     tmp.pop();
//                 }
//                 if (height[i] >= height[tmp.top()]) {
//                     sum = 0;
//                     for (int j = tmp.top() + 1; j < i; j++) {
//                         sum += height[j];
//                         height[j] = height[tmp.top()];
//                     }
//                     ans += (i - tmp.top() - 1) * height[tmp.top()] - sum;
//                     tmp.pop();
//                     tmp.push(i);
//                 }
//                 else {
//                     sum = 0;
//                     for (int j = tmp.top() + 1; j < i; j++) {
//                         sum += height[j];
//                         height[j] = height[i];
//                     }
//                     ans += (i - tmp.top() - 1) * height[i] - sum;
//                     tmp.push(i);
//                 }
//             }
//             else if (height[i] < height[tmp.top()]) {
//                 tmp.push(i);
//             }
//         }
//         return ans;
//     }
// };

class Solution {
public:
    int trap(vector<int>& height) {
        int n = height.size();
        if (n == 0) return 0;
        
        vector<int> left_max(n);
        left_max[0] = height[0];
        // 1. 从左到右,计算每个i的“左边最高墙”
        for (int i = 1; i < n; i++) {
            left_max[i] = max(left_max[i - 1], height[i]);
        }
        
        vector<int> right_max(n);
        right_max[n - 1] = height[n - 1];
        // 2. 从右到左,计算每个i的“右边最高墙”
        for (int i = n - 2; i >= 0; i--) {
            right_max[i] = max(right_max[i + 1], height[i]);
        }
        
        int ans = 0;
        // 3. 遍历每个柱子,累加它头顶的水
        for (int i = 0; i < n; i++) {
            ans += min(left_max[i], right_max[i]) - height[i];
        }
        
        return ans;
    }
};

root@NVR:~# dd if=/dev/sda1 of=/dev/mmcblk0 bs=1 skip=589303808 seek=589303808 c ount=134213632 ^C root@NVR:~# dd if=/dev/mmcblk0 bs=1 skip=589303808 count=1024 2>/dev/null | hexd ump -C 00000000 54 50 2d 4c 69 6e 6b 20 66 6f 72 6d 61 74 31 00 |TP-Link format1.| 00000010 00 00 00 01 00 00 02 00 00 00 00 01 00 00 00 48 |...............H| 00000020 00 00 00 00 00 00 00 00 00 00 00 04 31 00 00 00 |............1...| 00000030 00 00 00 03 00 00 00 00 00 00 00 04 32 00 00 00 |............2...| 00000040 00 00 00 04 00 00 00 00 00 00 00 04 35 00 00 00 |............5...| 00000050 00 00 00 01 00 00 00 01 00 00 00 0c 30 30 66 66 |............00ff| 00000060 30 30 34 31 62 35 30 00 00 00 00 00 00 00 00 00 |0041b50.........| 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 f6 |................| 00000200 66 e0 58 f2 d8 7c 96 0b 1d 9f 31 d6 95 08 14 b7 |f.X..|....1.....| 00000210 10 00 02 02 00 40 20 20 43 9f 92 ec 77 7f 35 61 |.....@ C...w.5a| 00000220 4f f2 fb bc 7f 83 19 ce f7 8c d6 88 9f 33 8b da |O............3..| 00000230 da e8 c2 fd 08 0e 32 9a 20 67 85 fe 88 b9 b7 61 |......2. g.....a| 00000240 74 97 aa 32 0d a5 b4 c6 d7 7f d7 51 52 4f 79 aa |t..2.......QROy.| 00000250 aa 1b 17 55 36 45 b1 04 95 73 b9 52 2b d8 c0 d7 |...U6E...s.R+...| 00000260 dc d7 b0 12 08 2d 65 1e 19 b9 c7 37 78 cc 4d fb |.....-e....7x.M.| 00000270 f3 6e 10 b7 a5 5c 27 e3 0f fc 30 d5 74 cc 8d f1 |.n...\'...0.t...| 00000280 e3 42 25 2b 26 ec de 1f 7f af be 03 52 92 27 4d |.B%+&.......R.'M| 00000290 0d 33 6b 71 36 d7 d3 30 dc 24 8d d4 59 84 b5 ff |.3kq6..0.$..Y...| 000002a0 09 3e 41 a9 b4 54 e4 bf e9 50 04 f5 61 3b a4 8e |.>A..T...P..a;..| 000002b0 9b de 27 d6 bc e6 43 9e 91 dd 53 8a af 55 52 ac |..'...C...S..UR.| 000002c0 9b 51 c4 07 7e 05 1b 78 1e 43 e2 27 96 33 35 8f |.Q..~..x.C.'.35.| 000002d0 57 91 8f 4e 23 af 9a 36 05 a7 0b b5 a8 c4 c8 53 |W..N#..6.......S| 000002e0 53 01 ac 19 c3 37 b6 e6 91 11 2d e8 e4 66 d7 88 |S....7....-..f..| 000002f0 77 14 31 d1 2e 05 0f fd 32 65 be 6b 7c 24 84 a8 |w.1.....2e.k|$..| 00000300 65 11 27 c1 95 8c 0b eb 2e 90 7b cd 17 ce cd 7a |e.'.......{....z| 00000310 07 f4 32 24 95 aa 47 9e 7c 8f 84 fd 3b dc 0c 67 |..2$..G.|...;..g| 00000320 07 29 ef 42 3f 95 f1 03 b5 da 47 60 fc e8 14 e2 |.).B?.....G`....| 00000330 41 53 d9 48 50 57 2f 20 9a 82 a0 37 42 54 0d b1 |AS.HPW/ ...7BT..| 00000340 10 41 10 a9 37 74 a7 e2 01 91 97 63 87 fc f8 8b |.A..7t.....c....| 00000350 59 c3 10 5d 1f 29 70 77 ec 5a 5d b1 47 ab c0 d7 |Y..].)pw.Z].G...| 00000360 53 61 b5 47 cd 7d d6 bb d3 98 49 00 b0 30 c4 f9 |Sa.G.}....I..0..| 00000370 62 3d 14 95 1e 72 c5 d1 a6 41 27 5d 62 c7 ea a6 |b=...r...A']b...| 00000380 0d fc 5d aa 87 f2 2c 94 db 00 22 f7 95 82 34 ac |..]...,..."...4.| 00000390 e0 a4 4c 63 fa f5 a5 3e 46 14 1e 97 01 69 ad 66 |..Lc...>F....i.f| 000003a0 b6 b3 d1 df 5b 1a 98 8e bd d2 16 b4 f4 ac a7 33 |....[..........3| 000003b0 f1 23 05 9c bc 9e 59 30 fd a3 1a 07 13 d9 f0 f0 |.#....Y0........| 000003c0 fe 95 d1 01 d1 b1 b9 a5 80 6a 57 fa 28 f7 28 c7 |.........jW.(.(.| 000003d0 b3 55 a7 b0 c6 56 b1 6c b4 a7 6f 2f e3 be 29 54 |.U...V.l..o/..)T| 000003e0 4f 13 e1 98 8f 65 b7 d7 00 d1 29 e5 3c 00 0b 69 |O....e....).<..i| 000003f0 dc 12 9a 4e 37 23 1d e5 19 bc b8 1e 0e 27 d3 9c |...N7#.......'..| 00000400 这样可以读写,但是为什么打不开呢
10-14
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值