题解 力扣 LeetCode 42 接雨水 双指针 滑动窗口 对撞指针 C++

题目传送门:

42. 接雨水 - 力扣(LeetCode)https://leetcode.cn/problems/trapping-rain-water/description/这题暴力一下就能过的,还有双指针-对撞指针的优化版本,感兴趣的可以去搜一下

不是我原创的写法我就不讲了

但是会在后面贴一份这个代码

这里介绍一种双指针-滑动窗口的写法

思路:

每轮操作找一个 "凹陷处",并统计。"凹陷处" 找法:

先找凹陷处左侧最高点,若满足 i < 边界 && 单调不降,则 i++

再找凹陷处右侧最高点,j 初始化为 i+1,若满足 j < 边界 && arr[j] < arr[i],则 j++

且在 j++ 之前,ret += arr[i] - arr[j]

一轮凹陷处找完后,i 更新为 j,继续向右进行下一轮操作

为保证凹陷处右侧最高点不低于凹陷处左侧最高点,需要找到全局最高点

然后从两侧依次向中间进行上述操作即可。换方向后 ++、< 等有方向性的操作符,记得改一下

代码:

class Solution
{
public:
    int trap(vector<int>& height)
    {
        int ret = 0, mx = 0;
        for (int i = 0; i < height.size(); i++) if (height[i] > height[mx]) mx = i;
        for (int i = 0, j = 0; i < mx && j < mx; i = j)
        {
            while (i < mx && height[i] <= height[i + 1]) i++;
            j = i + 1;
            while (j < mx && height[j] < height[i]) ret += height[i] - height[j], j++;
        }
        for (int i = height.size() - 1, j = height.size() - 1; i > mx && j > mx; i = j)
        {
            while (i > mx && height[i] <= height[i - 1]) i--;
            j = i - 1;
            while (j > mx && height[j] < height[i]) ret += height[i] - height[j], j--;
        }
        return ret;
    }
};

看起来有点多,实际上后两个 for 循环干的事是一样的,思考出其中一个就可以了

对撞指针代码:

class Solution
{
public:
    int trap(vector<int>& height)
    {
        int lmax = 0, rmax = 0, ret = 0;
        for (int l = 1, r = height.size() - 2; l <= r;)
        {
            if (height[l - 1] > lmax) lmax = height[l - 1];
            if (height[r + 1] > rmax) rmax = height[r + 1];
            if (lmax <= rmax && l <= r) ret += max(0, min(lmax, rmax) - height[l]), l++;
            if (lmax >= rmax && r >= l) ret += max(0, min(lmax, rmax) - height[r]), r--;
        }
        return ret;
    }
};

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值