接雨水 , 给定二维图,能容多少水

news2024/9/20 2:46:31

42. 接雨水 - 力扣(LeetCode)

看着就是非常常规的题目,所以非常有必要掌握。

最少也把O(n^2)的方法写出来吧。力扣官方题解的三种方法O(n)都挺好,不过可能有点难读,在此经过学习,写一篇自己的通俗理解。

0.O(n^2)

每次只看单个格子,这个格子能放多少水呢?

只要左边和右边都比自己高,就能放水了。

所以对于每个格子,分别找到最左和最优最高的,(根据木桶原理。。)此格子能放的水就是较低的那个。

class Solution {
public:
    map<int,int>mm;
    int trap(vector<int>& height) 
    {
        int ret = 0;
        int n = height.size();
        for(int i=0;i<n-1;i++)
        {
            int r;
            int maxv = 0,maxo = 0;
            for(r=i+1;r<n;r++)
            {
                if(height[r]>=height[i])
                    break;

                if(height[r] >= maxv)
                {
                    maxv = height[r];
                    maxo = r;
                }
            }
            if(r>=n)
            {
                int aim = maxv;
                for(int j = i+1;j<maxo;j++)
                {
                    if(height[j]<aim)
                        ret += aim - height[j];
                }
                i = maxo-1;
            }
            else
            {
                int aim = min(height[i],height[r]);
                for(int j = i+1;j<r;j++)
                {
                    if(height[j]<aim)
                        ret += aim - height[j];
                }
                i = r-1;
            }
        }
        return ret;
    }
};

1.动态规划

其实跟背包问题差别蛮大的。

看题解这张图其实就很好懂:

左往右遍历一次,右往左遍历一次,取覆盖区域并集即可。(哇这是动归吗)

class Solution {
public:
    map<int,int>mm;
    int trap(vector<int>& height) 
    {
        int n = height.size();
        vector<int>l(n),r(n);
        int tmp = 0;
        for(int i=0;i<n;i++)
        {
            tmp = max(tmp,height[i]);
            l[i] = tmp;
        }
        tmp = 0;
        for(int i=n-1;i>=0;i--)
        {
            tmp = max(tmp,height[i]);
            r[i] = tmp;
        }
        int ret = 0;
        for(int i=0;i<n;i++)
        {
            ret += min(l[i],r[i]) - height[i];
        }
        return ret;
    }
};

2.单调栈

是这样的一个解法。

如果多格高:

单调栈内放下标,他们的高度 从栈底到栈顶 是降低的。

直到遇见一个高的,那么栈顶的就可以作底去装水,高度为左边和右边较低者。

class Solution {
public:
    stack<int>sti;
    int trap(vector<int>& height) 
    {
        int n = height.size();
        int ret = 0;
        for(int i=0;i<n;i++)
        {
            while(sti.size()&&height[i] > height[sti.top()])
            {
                //这个是放水的平面
                int top = sti.top(); sti.pop();
                if(sti.size() == 0)break;//挨着的 | 上升的

                //补的是和左边这个高度差

                ret += (i-sti.top()-1) * (min(height[sti.top()],height[i]) - height[top]);
            }            
            sti.push(i);
        }
        return ret;
    }
};

3.双指针

和1类似,是对0的优化,不用每次都挨着找一遍。官方题解写法我看不太懂。但思想是明确的。

我们找左边最大 leftmax和右边最大 rightmax,那么中间就是容器能装水啦。

我们从低的一边向另一边走,遇到的格子能放的水都最多到低的这边的高度。

比如 leftmax <= rightmax ,左向右,每个格子都能装水到 leftmax。

直到遇见高边,且这个高边比右边最高还高,就可以从右向左了。

不然就一直往右装水:

class Solution {
    //其实右边有足够高的,左边底的绝对都能放进去水
public:
    int trap(vector<int>& height) 
    {
        int n = height.size();
        int l = 1,r = n-2;
        int leftmax = height[0],rightmax = height[n-1];
        int ret = 0;
        while(l<=r)
        {
            while(leftmax <= rightmax&&l<=r)
            {
                if(height[l] < leftmax)
                    ret += leftmax - height[l];
                else
                    leftmax = height[l];
                l++;
            }
            
            while(leftmax > rightmax&&l<=r)
            {
                if(height[r] < rightmax)
                    ret += rightmax - height[r];
                else
                    rightmax = height[r];
                r--;
            }
        }
        return ret;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1612021.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

淘宝购物更智能:taobao.item_search API接口实现关键字精准匹配

随着电子商务的飞速发展&#xff0c;淘宝作为中国最大的网络购物平台之一&#xff0c;为亿万消费者提供了便捷、丰富的购物体验。然而&#xff0c;在海量商品中快速找到符合自己需求的商品&#xff0c;一直是消费者面临的挑战。为了提升购物体验&#xff0c;淘宝开放平台提供了…

渐进式交付实践:通过 Argo Rollouts 和 FSM Gateway 实现金丝雀发布

渐进式交付&#xff08;Progressive delivery&#xff09;是一种软件发布策略&#xff0c;旨在更安全、更可控地将新版本软件逐步推出给用户。它是持续交付的进一步提升&#xff0c;允许开发团队在发布新版本时拥有更细粒度的控制&#xff0c;例如可以根据用户反馈、性能指标和…

树莓派3B长时间不操作屏幕息屏无信号处理

树莓派外接显示器&#xff0c;需长时间展示某个网页&#xff0c;经过一段时间&#xff0c;显示器屏幕会黑掉显示无信号。 需修改 /etc/lightdm/lightdm.conf 配置文件中新增如下两行并重启。 xserver-commandX -s 0 dpms sleep-inactive-timeout0

系统架构设计精华知识

数据流风格&#xff1a;适合于分阶段做数据处理&#xff0c;交互性差&#xff0c;包括&#xff1a;批处理序列、管理过滤器。调用/返回风格&#xff1a;一般系统都要用到&#xff0c;包括&#xff1a;主程序/子程序&#xff0c;面向对象&#xff0c;层次结构&#xff08;分层越…

图像分类:Pytorch实现Vision Transformer(ViT)进行图像分类

图像分类&#xff1a;Pytorch实现Vision Transformer&#xff08;ViT&#xff09;进行图像分类 前言相关介绍ViT模型的基本原理&#xff1a;ViT的特点与优势&#xff1a;ViT的缺点&#xff1a;应用与拓展&#xff1a; 项目结构具体步骤准备数据集读取数据集设置并解析相关参数定…

人工智能论文GPT-3(3):2020.5 Language Models are Few-Shot Learners;架构;训练数据集;开源

2.1 模型与架构 我们使用了与GPT-2相同的模型和架构&#xff0c;包括其中描述的改进初始化、预归一化和可逆分词技术&#xff0c;但有所不同的是&#xff0c;我们在Transformer的各层中使用了交替的密集和局部带状稀疏注意力模式&#xff0c;类似于Sparse Transformer 。为了研…

RocketMQ异步消息发送失败重试DEMO

producer.setRetryTimesWhenSendAsyncFailed(3); 都知道通过设置&#xff0c;尝试是在MQClientAPIImpl 中完成 其重试是通过MQClientAPIImpl的onExceptionImpl方法来实现&#xff0c;它会先判断重试次数&#xff0c;然后重新调用sendMessageAsync方法进行重试&#xff0c;调用…

【氧化镓】Ga2O3 MOSFET器件的单SEB机制TCAD研究

本文是一篇关于氧化镓(Ga2O3)金属氧化物半导体场效应晶体管(MOSFET)在单粒子烧毁(single event burnout, SEB)事件中的机制研究的文章。文章通过使用技术计算机辅助设计(TCAD)模拟来探究侧向耗尽型氧化镓MOSFET设备在SEB中的敏感区域和安全操作电压&#xff0c;并提出了辐射损伤…

Linux环境变量深度解析

文章目录 一、引言二、环境变量的基本概念1、环境变量的定义2、环境变量的作用与意义 三、环境变量的导入1、导入所需文件2、登陆时的导入 四、环境变量的设置方法1、查看环境变量的方式2、使用export命令临时设置环境变量3、修改配置文件以永久设置环境变量 五、命令行参数与环…

用户的流失预测分析

项目背景 随着电信行业的持续发展&#xff0c;运营商们开始更加关注如何扩大他们的客户群体。研究表明&#xff0c;获取新客户所需的成本要远高于保留现有客户的成本。因此&#xff0c;在激烈的竞争中&#xff0c;保留现有客户成为了一个巨大的挑战。在电信行业中&#xff0c;…

ADSP-21479的开发详解五(AD1939 C Block-Based Talkthru 48 or 96 kHz)音频直通

硬件准备 ADSP-21479EVB开发板&#xff1a; 产品链接&#xff1a;https://item.taobao.com/item.htm?id555500952801&spma1z10.5-c.w4002-5192690539.11.151441a3Z16RLU AD-HP530ICE仿真器&#xff1a; 产品链接&#xff1a;https://item.taobao.com/item.htm?id38007…

AI大模型日报#0420:开源模型击败GPT-4、西湖大学蛋白质通用大模型、GPT的七条经验

导读&#xff1a; 欢迎阅读《AI大模型日报》&#xff0c;内容基于Python爬虫和LLM自动生成。目前采用“文心一言”生成了每条资讯的摘要。 标题: 开源模型打败GPT-4&#xff01;LLM竞技场最新战报&#xff0c;Cohere Command R上线 摘要: GPT-4在LLM竞技场被开源模型Cohere的…

算法课程笔记——集合set

3复杂度不稳定 删一个和删除全部 注意iter是类 遍历是无序的

AI时代,操作系统交互的革命性变革

AI时代对操作系统交互的影响 对于2024年的智能手机厂商们来说&#xff0c;在冲击高端市场的路上有一场绝对输不起的硬仗&#xff0c;那就是AI大模型的落地之战。 OpenAI的ChatGPT引爆了全球AIGC&#xff08;生成式人工智能&#xff09;热潮&#xff0c;短短一年时间里&#xff…

使用Python爬取易车网汽车信息(含x-sign参数逆向分析)

文章目录 1. 写在前面2. 接口分析3. 断点分析3. 算法还原 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致…

【论文精读】Attention is all you need

摘要 主要的序列转换模型是基于复杂的循环或卷积神经网络&#xff0c;其中包括一个编码器和一个解码器。性能最好的模型还通过一种注意力机制将编码器和解码器连接起来。我们提出了一种新的简单的网络架构&#xff0c;Transformer&#xff0c;完全基于注意机制&#xff0c;完全…

C++设计模式:适配器模式(十四)

1、定义与动机 定义&#xff1a;将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作。 动机&#xff1a; 在软件系统中&#xff0c;由于应用环境的变化&#xff0c;常常需要将“一些现存的对象”放在新的环境…

SpringBoot3 + Vue3 + Element-Plus + TS 实现动态二级菜单级联选择器

SpringBoot3 Vue3 Element-Plus TS 实现动态二级菜单选择器 1、效果展示1.1 点击效果1.2 选择效果1.3 返回值1.4 模拟后端返回数据 2、前端代码2.1 UnusedList.vue2.2 goodsType.ts2.3 http.ts 3、后端代码3.1 GoodsCategoryController.java3.2 GoodsCategoryService.java3.…

内网抓取Windows密码明文与hashdump思考题笔记整理

目录 思考题 第一题 第二题 第三题 第四题 第五题 思考题 1.windows登录的明文密码&#xff0c;存储过程是怎么样的&#xff0c;密文存在哪个文件下&#xff0c;该文件是否可以打开&#xff0c;并且查看到密文 2.我们通过hashdump 抓取出 所有用户的密文&#xff0c;分为…

Mysql学习2

目录 一.数据库&#xff1a; 1.创建数据库&#xff1a; 2.查看数据库&#xff1a; 3.备份恢复数据库&#xff1a; 二.表 1.创建表指令&#xff1a; 2.MySQL常用数据类型&#xff1a; 3.删除与修改表&#xff08;重点&#xff09;&#xff1a; 4.数据库CRUD语句&#xf…