【力扣每日一题】2023.7.23 接雨水

这篇具有很好参考价值的文章主要介绍了【力扣每日一题】2023.7.23 接雨水。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

题目:

示例:

分析:

代码+运行结果:


题目:

【力扣每日一题】2023.7.23 接雨水,力扣每日一题,leetcode,算法,c++,数据结构

示例:

【力扣每日一题】2023.7.23 接雨水,力扣每日一题,leetcode,算法,c++,数据结构

分析:

接雨水是力扣里非常经典的一道单调栈的题目,使用单调栈的做法就是从左到右将高度依次入栈,保持栈内从栈顶开始升序,在遇到比栈顶更高的高度后,则弹出栈顶元素,并开始按行来计算所积雨水数量,再将后面来的高度入栈。

由于这题很经典,并且讲解的人也不少,因此我就不说单调栈的解法了,我这里介绍一种按列积水的方法。

这里我把示例2做成了图方便看:

【力扣每日一题】2023.7.23 接雨水,力扣每日一题,leetcode,算法,c++,数据结构

 我们可以注意到不管是示例一还是示例二,数组的左右两边的列是一定没有积水的,有积水的列都是左边右边都有比自身更高的柱子。

因此我们发现了一个柱子所在的列有没有积水,是根据自身左右边的最高的高度来决定了,因此我们可以用两个数组(一个二维数组也行)来缓存住某索引所在的位置,它的左边最高的高度是多少,以及它的右边最高的高度是多少。

然后这个柱子左右最高的高度中较小的高度减去自身的高度就是本列能积水的最多数量。

我们需要正序遍历一边获取每个柱子左边最高的高度。

再逆序遍历一边获取每个柱子右边最高的高度。

再任意顺序遍历一边将刚刚获取的左右最高高度按照我们刚才说的公式来计算积水数。

【力扣每日一题】2023.7.23 接雨水,力扣每日一题,leetcode,算法,c++,数据结构

但是这样要遍历三遍,这里有一个更加巧妙的双指针的做法。

我们定义首尾指针分别指向数组的开头和结尾,并且使用左指针来更新左边最高的高度,用右指针来更新右边最高的高度。

哪个指针指向的高度更小,我们就用刚才的公式来计算那一列所积的水,并且移动指针,再更新相应的最高值。

这样左右指针一起遍历一边数组,比最开始遍历3次相比少遍历了2次。

 文章来源地址https://www.toymoban.com/news/detail-610313.html

【力扣每日一题】2023.7.23 接雨水,力扣每日一题,leetcode,算法,c++,数据结构

那么大家可能会有疑惑,有没有可能出现这样一种情况,就是我现在要计算一个列的积水,但是这一列的左(右)高度并不是我这一列的左(右)边最大值,像下面这样:

【力扣每日一题】2023.7.23 接雨水,力扣每日一题,leetcode,算法,c++,数据结构

 其实大家再从头推导一边就会发现,这样的情况是不会发生的,真实的情况是下面这样:

【力扣每日一题】2023.7.23 接雨水,力扣每日一题,leetcode,算法,c++,数据结构

 我们每次计算并移动的都是相对更短的边,因此上面这种少计算积水数的情况是不会发生的。

代码+运行结果:

class Solution {
public:
    int trap(vector<int>& height) {
        int n=height.size();
        //缓存住某索引位置上左边的最高边和右边的最高边
        vector<int>lcache(n),rcache(n);
        int temp=0;
        for(int i=0;i<height.size();++i){
            temp=max(temp,height[i]);
            lcache[i]=temp;
        }
        temp=0;
        for(int i=n-1;i>=0;--i){
            temp=max(temp,height[i]);
            rcache[i]=temp;
        }
        int res=0;
        //某索引那一列能储水的部分就是左右两边最矮的一边减去自身高度
        for(int i=0;i<n;i++){
            res+=min(lcache[i],rcache[i])-height[i];
        }
        return res;
    }
};

【力扣每日一题】2023.7.23 接雨水,力扣每日一题,leetcode,算法,c++,数据结构

class Solution {
public:
    int trap(vector<int>& height) {
        int l=0,r=height.size()-1;
        int maxL=height[l],maxR=height[r];
        int res=0;
        //双指针
        while(l<r){
            //更新左右的最高边
            maxL=max(maxL,height[l]);
            maxR=max(maxR,height[r]);
            if(maxR>maxL){
                res+=maxL-height[l++];
            }else{
                res+=maxR-height[r--];
            }
        }
        return res;
    }
};

【力扣每日一题】2023.7.23 接雨水,力扣每日一题,leetcode,算法,c++,数据结构

 

到了这里,关于【力扣每日一题】2023.7.23 接雨水的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 2023-07-16力扣每日一题

    链接: 834. 树中距离之和 题意: 给定一个树,有n个节点,需要得到每个节点与其他节点的距离和 解: 还以为是弗洛伊德,一看范围3E4直接晕倒 想了四个小时,实在是想不出来了,看了一下评论里的转移公式 设 DP[i] 为节点 i 与其他节点的距离和, DP[F] 是节点 i 的父节点与

    2024年02月16日
    浏览(12)
  • 2023-07-15力扣每日一题

    链接: 18. 四数之和 题意: 一个数组n,一个目标值t,在数组内找四个数字和等于t,求能有多少种组合 解: 0716:一看怎么昨天卡没打,原来昨天做的第一题不是每日一题,麻了 n很小,200,那么 先排序 ,然后弄一个 双指针开双循环 l,r ,确定每个组合的最大数字-数字4和最

    2024年02月16日
    浏览(10)
  • 2023-07-27力扣每日一题

    链接: 2500. 删除每行中的最大值 题意: 简单题,每次删除每一行的最大值,存储每次删除中最大的数字 解: 对行排序,每一列取最大值 实际代码: 限制: m == grid.length n == grid[i].length 1 = m, n = 50 1 = grid[i][j] = 100

    2024年02月15日
    浏览(9)
  • 2023-07-29力扣每日一题

    链接: 141. 环形链表 题意: 求链表是否有环 解: 刚好昨天做完的初级算法链表题,翻转和暴力 实际代码: 限制: 链表中节点的数目范围是 [0, 104] -105 = Node.val = 105 pos 为 -1 或者链表中的一个 有效索引 。

    2024年02月15日
    浏览(9)
  • 2023-08-18力扣每日一题

    链接: 1388. 3n 块披萨 题意: 一个长度3n的环,选n次数字,每次选完以后相邻的数字会消失,求选取结果最大值 解: 这波是~~(ctrl)CV工程师了~~ 核心思想是选取 n个不相邻 的元素一定 合法 ,我推不出来,猜一猜倒是可以O.o DP[i][j] 表示从 [0,i] 中选取 j 个数字的最大值 初始

    2024年02月12日
    浏览(14)
  • 2023-08-26力扣每日一题

    链接: 228. 汇总区间 题意: 升序数组找连续区间 解: 简单遍历题 实际代码: 限制: 0 = nums.length = 20 -231 = nums[i] = 231 - 1 nums 中的所有值都 互不相同 nums 按升序排列

    2024年02月11日
    浏览(7)
  • 2023-08-25力扣每日一题

    链接: 1448. 统计二叉树中好节点的数目 题意: 判断根节点到每个节点X的过程中,如果没有值大于X,则该节点为好节点,求好节点数量 解: 由于求根节点到其他节点的路径,则使用dfs算法,更新路径中的最大值即可 实际代码: 限制: 二叉树中节点数目范围是 [1, 10^5] 。

    2024年02月10日
    浏览(15)
  • 2023-08-09力扣每日一题

    链接: 1281. 整数的各位积和之差 题意: 十进制每一位的积减去每一位的和 解: 十进制位处理 实际代码: 限制: 1 = n = 10^5

    2024年02月13日
    浏览(10)
  • 2023-09-02力扣每日一题

    链接: 2511. 最多可以摧毁的敌人城堡数目 题意和解 : 阅读理解题,要从1到-1或-1到1,中间只能有0,求最多能有多少0 实际代码: 限制: 1 = forts.length = 1000 -1 = forts[i] = 1

    2024年02月10日
    浏览(9)
  • 2023-09-01力扣每日一题

    链接: 2240. 买钢笔和铅笔的方案数 题意: 一共total元,两种笔分别cost1和cost2元,求能买的的笔的所有情况,不要求花光钱 解: 枚举其中一个数字就行 实际代码: 限制: 1 = total, cost1, cost2 = 106

    2024年02月10日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包