【力扣每日一题】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-12力扣每日一题

    链接: 2544. 交替数字和 题意: 一个数字字符串,根据符号求和,符号规律+ - + - +… 解: 简单题,遍历 实际代码: 手写: 函数!小子: 限制: 1 = n = 109

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

    链接: 1267. 统计参与通信的服务器 题意: 同行同列可以发生通信,求能发生通信的机器数量 解: 标记每行/每列的机器个数即可 实际代码: 限制: m == grid.length n == grid[i].length 1 = m = 250 1 = n = 250 grid[i][j] == 0 or 1

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

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

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

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

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

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

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

    链接: https://leetcode.cn/problems/maximum-alternating-subsequence-sum/ 题意: 给定一个数组,求一个子序列,使这个子序列的 奇数位和-偶数位和 最大(下标从1开始的话|反正第一个数是+) 解: 找下坡,曲折处两个分下坡大于一个总下坡(如图) 实际代码: 思维: DP?: 限制: 1 = nu

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

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

    2024年02月16日
    浏览(38)
  • 2023-08-29力扣每日一题

    链接: 823. 带因子的二叉树 题意: 用给的数字建二叉树,要求父节点是子节点的乘积 解: 乐了 1500ms+30MB //注释版120ms+18MB 实际代码: 限制: 1 = arr.length = 1000 2 = arr[i] = 109 arr 中的所有值 互不相同

    2024年02月11日
    浏览(26)
  • 2023-09-07力扣每日一题

    链接: [2594. 修车的最少时间](https://leetcode.cn/problems/form-smallest-number-from-two-digit-arrays/) 题意: 一个能力R的人R*N*N分钟修N辆车,求最快多久修完(多人多车) 解: 二分很好想,主要是怎么检查(数学废物润去看题解了) 实际代码: 限制: 1 = ranks.length = 105 1 = ranks[i] = 100 1 = ca

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

    链接: 833. 字符串中的查找与替换 题意: n组操作,其中第i组: 检查 子字符串 sources[i] 是否出现在 原字符串 s 的索引 indices[i] 处。 如果没有出现, 什么也不做 。 如果出现,则用 targets[i] 替换 该子字符串。 所有替换操作必须 同时 发生,这意味着替换操作不应该影响彼此

    2024年02月12日
    浏览(37)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包