当前位置:首页 > 力扣 > 力扣面试17.21题解:双指针算法高效求解接雨水问题(含代码注释与优化思路)

力扣面试17.21题解:双指针算法高效求解接雨水问题(含代码注释与优化思路)

2个月前 (07-21)

力扣面试17.21题解:双指针算法高效求解接雨水问题(含代码注释与优化思路) 力扣面试题 双指针算法 动态规划 力扣题解 线性扫描 第1张

一、题目解读

力扣面试17.21题(接雨水问题)要求计算给定高度数组中,凹槽结构能容纳的雨水总量。例如,数组[0,1,0,2,1,0,1,3,2,1,2,1]形成的凹槽可积水6单位(可视化后凹陷部分水量)。核心难点在于高效遍历数组,精准计算各位置积水,避免冗余计算。

二、解题思路

采用双指针法,巧妙结合动态规划思想:

1. 核心原理:从数组左右两端同时向内逼近,实时记录两侧最大高度。积水由“短板效应”决定——每次移动较低侧指针,利用另一侧的最大高度作为“虚拟墙”计算当前位置水量。

2. 优势:避免全局遍历与空间消耗,时间复杂度降至O(n),空间O(1)。

三、解题步骤

1. 初始化:

    左指针left=0,右指针right=height.size()-1;

    两侧最大高度left_max=0, right_max=0,水量water=0。

2. 循环逼近:

    更新当前两侧最大高度:left_max = max(left_max, height[left]), right_max = max(right_max, height[right]);

    若height[left] < height[right](左低右高),则左移指针:积水为left_max - height[left](虚拟右墙与当前高度的差),left++;反之右移right--。

3. 终止条件:left >= right时所有积水计算完毕。

四、代码与注释

#include <vector>
#include <algorithm>
using namespace std;

class Solution {
public:
    int trap(vector<int>& height) {
        if (height.empty()) return 0; // 空数组特判
        
        int left = 0, right = height.size() - 1;
        int left_max = 0, right_max = 0;
        int water = 0;
        
        while (left < right) {
            // 更新左右最大值
            left_max = max(left_max, height[left]); // 动态维护左墙高度
            right_max = max(right_max, height[right]); // 动态维护右墙高度
            
            // 较小的一边决定当前能存的水量
            if (height[left] < height[right]) {
                water += left_max - height[left]; // 左低时,积水=左墙高度-当前高度
                left++; // 左指针内移
            } else {
                water += right_max - height[right]; // 右低同理
                right--;
            }
        }
        
        return water;
    }
};

注释解析:关键步骤通过“动态维护虚拟墙高度”与“短板移动”实现水量累加,避免全局搜索。

五、总结

1. 算法亮点:

○ 双指针+动态更新策略,将二维积水问题转化为线性遍历,降低复杂度。

○ 代码简洁,无额外空间开销,适用于大规模数据场景。

2. 优化方向:

○ 可进一步探索单调栈分治策略,但双指针已满足面试需求。

3. 应用场景:该思想适用于“区间最值决定结果”的类似问题,如柱状最大面积计算等。


原创内容 转载请注明出处

分享给朋友:

相关文章

CSP-J 2019纪念品题解(洛谷P5662):动态规划+完全背包问题的实战应用

CSP-J 2019纪念品题解(洛谷P5662):动态规划+完全背包问题的实战应用

一、题目解读2019年CSP-J的“纪念品”问题(对应洛谷P5662)要求玩家在T天内通过买卖纪念品最大化金币收益。每天可交易N种商品,需计算最优策略下的最终金币数。题目强调动态规划思维与资源分配优化...

CSP-J方格取数题解|动态规划解法|洛谷P7074代码解析

CSP-J方格取数题解|动态规划解法|洛谷P7074代码解析

一、题目解读题目要求在一个n×m的网格中,从左上角到右下角选择一条路径,路径上的数字可重复取用,求取数之和的最大值。路径限制为仅能向右或向下移动。需注意路径的灵活性与重复取数的可能性,传统单向动态规划...

2024蓝桥杯省赛B组“传送阵”题解(C++代码+图论算法优化)

2024蓝桥杯省赛B组“传送阵”题解(C++代码+图论算法优化)

一、题目解读2024年蓝桥杯省B组“传送阵”题目要求处理一个包含n个节点的图,节点间存在单向传输关系。每个节点i可传送至a[i]指定的节点,形成可能存在的环结构。题目需求解从任意节点出发能到达的最长路...

LeetCode 120题三角形最小路径和最优解法:动态规划详解与代码实现

LeetCode 120题三角形最小路径和最优解法:动态规划详解与代码实现

一、题目解读LeetCode 120题“三角形最小路径和”要求给定一个由数字组成的三角形,从顶部开始向下移动,每次可向左或向右移动一格,计算从顶至底的最小路径和。三角形以二维向量形式给出,每层元素数量...

洛谷P4551题解题报告:图论与Trie树优化异或路径问题的实战解析

洛谷P4551题解题报告:图论与Trie树优化异或路径问题的实战解析

一、题目解读洛谷P4551题要求在一个无向图中,寻找任意两点路径权值异或后的最大值。题目输入为图的边信息(点数n和n-1条边),每条边包含起点、终点及权值。需输出所有路径中权值异或的最大值。问题核心在...

CSP-J 2019公交换乘题解析:基于队列优化的动态规划代码详解

CSP-J 2019公交换乘题解析:基于队列优化的动态规划代码详解

一、题目解读CSP-J 2019年的“公交换乘”题目(洛谷P5661)要求模拟地铁与公交交替出行的费用计算。题目核心在于地铁消费会产生优惠券,而公交可在45分钟内使用优惠券抵扣车费。需要处理n条出行记...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。