当前位置: 首页 > news >正文

力扣刷题----42. 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 
输入:height = [4,2,0,3,2,5]
输出:9

自己写的

 public class Solution

 {

     public int Trap(int[] height)

     {

         int[] Theleft=new int[height.Length];

         int[] Therightside=new int[height.Length];

         int[] res=new int[height.Length];

         int result = 0;

         int left=Theleft[0];

         int right = Therightside[Therightside.Length - 1];

         for (int i = 0; i < height.Length; i++)

         {

             if (left <= height[i])

             {

                 Theleft[i] = 0;

                 left = height[i];

             }

             else

             {

                 Theleft[i] = left - height[i] ;

                 

             }

         }

         for (int i = height.Length-1; i >= 0; i--)

         {

             if (right <= height[i])

             {

                 Therightside[i] = 0;

                 right = height[i];

             }

             else

             {

                 Therightside[i] = right - height[i];

                 

             }

         }

         for (int i = 0; i < height.Length; i++)

         {

             res[i]= Math.Min(Theleft[i], Therightside[i]);

         }

         for (int i = 0; i < res.Length; i++)

         {

             result=result + res[i];

         }

         return result;

     }

 }

空间复杂度比较高 和官方的第一个题解一样

方法一:动态规划
对于下标 i,下雨后水能到达的最大高度等于下标 i 两边的最大高度的最小值,下标 i 处能接的雨水量等于下标 i 处的水能到达的最大高度减去 height[i]。

朴素的做法是对于数组 height 中的每个元素,分别向左和向右扫描并记录左边和右边的最大高度,然后计算每个下标位置能接的雨水量。假设数组 height 的长度为 n,该做法需要对每个下标位置使用 O(n) 的时间向两边扫描并得到最大高度,因此总时间复杂度是 O(n 
2
 )。

上述做法的时间复杂度较高是因为需要对每个下标位置都向两边扫描。如果已经知道每个位置两边的最大高度,则可以在 O(n) 的时间内得到能接的雨水总量。使用动态规划的方法,可以在 O(n) 的时间内预处理得到每个位置两边的最大高度。

创建两个长度为 n 的数组 leftMax 和 rightMax。对于 0≤i<n,leftMax[i] 表示下标 i 及其左边的位置中,height 的最大高度,rightMax[i] 表示下标 i 及其右边的位置中,height 的最大高度。

显然,leftMax[0]=height[0],rightMax[n−1]=height[n−1]。两个数组的其余元素的计算如下:

当 1≤i≤n−1 时,leftMax[i]=max(leftMax[i−1],height[i]);

当 0≤i≤n−2 时,rightMax[i]=max(rightMax[i+1],height[i])。

因此可以正向遍历数组 height 得到数组 leftMax 的每个元素值,反向遍历数组 height 得到数组 rightMax 的每个元素值。

在得到数组 leftMax 和 rightMax 的每个元素值之后,对于 0≤i<n,下标 i 处能接的雨水量等于 min(leftMax[i],rightMax[i])−height[i]。遍历每个下标位置即可得到能接的雨水总量。

 但是官方的双指针更优化

方法三:双指针
动态规划的做法中,需要维护两个数组 leftMax 和 rightMax,因此空间复杂度是 O(n)。是否可以将空间复杂度降到 O(1)?

注意到下标 i 处能接的雨水量由 leftMax[i] 和 rightMax[i] 中的最小值决定。由于数组 leftMax 是从左往右计算,数组 rightMax 是从右往左计算,因此可以使用双指针和两个变量代替两个数组。

维护两个指针 left 和 right,以及两个变量 leftMax 和 rightMax,初始时 left=0,right=n−1,leftMax=0,rightMax=0。指针 left 只会向右移动,指针 right 只会向左移动,在移动指针的过程中维护两个变量 leftMax 和 rightMax 的值。

当两个指针没有相遇时,进行如下操作:

使用 height[left] 和 height[right] 的值更新 leftMax 和 rightMax 的值;

如果 height[left]<height[right],则必有 leftMax<rightMax,下标 left 处能接的雨水量等于 leftMax−height[left],将下标 left 处能接的雨水量加到能接的雨水总量,然后将 left 加 1(即向右移动一位);

如果 height[left]≥height[right],则必有 leftMax≥rightMax,下标 right 处能接的雨水量等于 rightMax−height[right],将下标 right 处能接的雨水量加到能接的雨水总量,然后将 right 减 1(即向左移动一位)。

当两个指针相遇时,即可得到能接的雨水总量。

下面用一个例子 height=[0,1,0,2,1,0,1,3,2,1,2,1] 来帮助读者理解双指针的做法。

 

class Solution {public int trap(int[] height) {int ans = 0;int left = 0, right = height.length - 1;int leftMax = 0, rightMax = 0;while (left < right) {leftMax = Math.max(leftMax, height[left]);rightMax = Math.max(rightMax, height[right]);if (height[left] < height[right]) {ans += leftMax - height[left];++left;} else {ans += rightMax - height[right];--right;}}return ans;}
}

关于动态规划的介绍

动态规划(Dynamic Programming,简称DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学等领域中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。

动态规划经常用于求解具有重叠子问题和最优子结构性质的问题。这里的“重叠子问题”是指在递归算法中反复出现的问题,而“最优子结构”是指问题的最优解包含其子问题的最优解。

动态规划的关键步骤:

  1. 识别子问题:将问题分解为小的子问题,这些子问题往往是原问题的规模较小的版本。

  2. 确定状态:定义问题的解状态,通常用变量表示,例如 dp[i]

  3. 确定状态转移方程:找出状态之间的关系,即当前状态是如何由之前的一个或多个状态推导出来的。

  4. 确定初始状态和边界条件:确定状态转移的起点,即基本情况或边界条件。

  5. 确定求解策略:是自底向上(从最小的子问题开始解决)还是自顶向下(递归地解决)。

  6. 构造最优解:根据子问题的解构造原问题的解。

动态规划的常见应用:

  • 斐波那契数列:计算第n个斐波那契数。
  • 背包问题:在不超过背包容量的前提下,选择物品以最大化价值。
  • 最长公共子序列:找出两个序列的最长公共子序列。
  • 最短路径问题:如贝尔曼-福特算法解决带负权边的最短路径问题。
  • 矩阵链乘问题:计算矩阵乘法的最少操作次数。
  • 编辑距离问题:计算两个字符串之间的最小编辑距离。

示例:斐波那契数列的动态规划解法

斐波那契数列是一个典型的动态规划问题,其递归解法存在大量重复计算。动态规划解法如下:

  1. 状态定义dp[i] 表示斐波那契数列的第 i 个数。
  2. 状态转移方程dp[i] = dp[i-1] + dp[i-2]
  3. 初始状态dp[0] = 0dp[1] = 1
  4. 循环计算:从 2 到 n,依次计算 dp[i]
using System;class Program
{// 动态规划计算斐波那契数列的第n项static long Fibonacci(int n){if (n <= 1)return n;long[] dp = new long[n + 1];dp[0] = 0;dp[1] = 1;for (int i = 2; i <= n; i++){dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];}static void Main(){int n = 10; // 计算斐波那契数列的第10项long result = Fibonacci(n);Console.WriteLine($"Fibonacci of {n} is {result}");}
}

动态规划是一种非常强大的方法,可以显著提高算法的效率,特别是在解决具有重复子问题和最优子结构的问题时。

相关文章:

力扣刷题----42. 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图&#xf…...

【论文精读】 | 基于图表示的视频抑郁症识别的两阶段时间建模框架

文章目录 0、Description1、Introduction2、Related work2.1 Relationship between depression and facial behaviours2.2 Video-based automatic depression analysis2.3 Facial graph representation 3、The proposed two-stage approach3.1 Short-term depressive behaviour…...

采集PCM,将base64片段转换为wav音频文件

需求 开始录音——监听录音数据——结束录音 在监听录音数据过程中&#xff1a;客户端每100ms给前端传输一次数据&#xff08;pcm数据转成base64&#xff09;&#xff0c;前端需要将base64片段解码、合并、添加WAV头、转成File、上传到 OSS之后将 url 给到服务端处理。 {num…...

eclipse ui bug

eclipse ui bug界面缺陷&#xff0c;可能项目过多&#xff0c;特别maven项目过多&#xff0c;下载&#xff0c;自动编译&#xff0c;加载更新界面异常 所有窗口死活Restore不回去了 1&#xff09;尝试创建项目&#xff0c;还原界面&#xff0c;失败 2&#xff09;关闭所有窗口&…...

前端获取blob文件格式的两种格式

第一种,后台传递给前台是base64格式的JSON数据 这时候前台拿到base64格式的数据可以通过内置的atob解码方法结合new Uint8Array和new Blob方法转换成blob类型的数据格式,然后可以使用blob数据格式进行操作,虽然base64转换成blob要经过很多步骤,但幸运的是这些步骤都是固定的,因…...

向日葵RCE复现(CNVD-2022-10270/CNVD-2022-03672)

一、环境 1.1 网上下载低版本的向日葵<2022 二、开始复现 2.1 在目标主机上打开旧版向日葵 2.2 首先打开nmap扫描向日葵主机端口 2.3 在浏览器中访问ip端口号cgi-bin/rpc?actionverify-haras &#xff08;端口号&#xff1a;每一个都尝试&#xff0c;直到获取到session值…...

Postman中的负载均衡测试:确保API的高可用性

Postman中的负载均衡测试&#xff1a;确保API的高可用性 在微服务架构和分布式系统中&#xff0c;API的负载均衡是确保系统高可用性和可扩展性的关键技术之一。Postman作为一个多功能的API开发和测试平台&#xff0c;提供了多种工具来帮助测试人员模拟高负载情况下的API表现。…...

anaconda+tensorflow+keras+jupyter notebook搭建过程(CPU版)

AnacondaTensorFlowKeras 环境搭建教程...

LitCTF2024赛后web复现

复现要求&#xff1a;看wp做一遍&#xff0c;自己做一遍&#xff0c;第二天再做一遍。&#xff08;一眼看出来就跳过&#xff09; 目录 [LitCTF 2024]浏览器也能套娃&#xff1f; [LitCTF 2024]一个....池子&#xff1f; [LitCTF 2024]高亮主题(划掉)背景查看器 [LitCTF 2…...

Elasticsearch:跨集群使用 ES|QL

警告&#xff1a;ES|QL 的跨集群搜索目前处于技术预览阶段&#xff0c;可能会在未来版本中更改或删除。Elastic 将努力解决任何问题&#xff0c;但技术预览中的功能不受官方 GA 功能的支持 SLA 约束。 使用 ES|QL&#xff0c;你可以跨多个集群执行单个查询。 前提&#xff1a; …...

学习笔记4:docker和k8s选择简述

docker和 k8s 占用资源 使用客户体量Docker 和 Kubernetes&#xff08;K8s&#xff09;都是流行的容器化技术&#xff0c;但它们在资源管理和使用上有一些不同。以下是关于两者资源占用和使用客户体量的详细比较&#xff0c;基于具体数据和信息&#xff1a; Docker 资源占用…...

关于锁策略

在Java中对于多线程来说&#xff0c;锁是一种重要且必不可少的东西&#xff0c;那么我们将如何使用以及在什么时候使用什么样的锁呢&#xff1f;请各位往下看 悲观锁VS乐观锁 悲观锁&#xff1a; 在多线程环境中&#xff0c;冲突是非常常见的&#xff0c;所以在执行操作之前…...

昇思25天学习打卡营第3天|基础知识-数据集Dataset

目录 环境 环境 导包 数据集加载 数据集迭代 数据集常用操作 shuffle map batch 自定义数据集 可随机访问数据集 可迭代数据集 生成器 MindSpore提供基于Pipeline的数据引擎&#xff0c;通过数据集&#xff08;Dataset&#xff09;和数据变换&#xff08;Transfor…...

C++11新特性——智能指针——参考bibi《 原子之音》的视频以及ChatGpt

智能指针 一、内存泄露1.1 内存泄露常见原因1.2 如何避免内存泄露 二、实例Demo2.1 文件结构2.2 Dog.h2.3 Dog.cpp2.3 mian.cpp 三、独占式智能指针:unique _ptr3.1 创建方式3.1.1 ⭐从原始(裸)指针转换&#xff1a;3.1.2 ⭐⭐使用 new 关键字直接创建&#xff1a;3.1.3 ⭐⭐⭐…...

“微软蓝屏”全球宕机,敲响基础软件自主可控警钟

上周五&#xff0c;“微软蓝屏”“感谢微软 喜提假期”等词条冲上热搜&#xff0c;全球百万打工人受此影响&#xff0c;共同见证这一历史性事件。据微软方面发布消息称&#xff0c;旗下Microsoft 365系列服务出现访问中断。随后在全球范围内&#xff0c;包括企业、政府、个人在…...

【Linux C | 网络编程】进程间传递文件描述符socketpair、sendmsg、recvmsg详解

我们的目的是&#xff0c;实现进程间传递文件描述符&#xff0c;是指 A进程打开文件fileA,获得文件描述符为fdA&#xff0c;现在 A进程要通过某种方法&#xff0c;传递fdA&#xff0c;使得另一个进程B&#xff0c;获得一个新的文件描述符fdB&#xff0c;这个fdB在进程B中的作用…...

高并发内存池(六)Page Cache回收功能的实现

当Page Cache接收了一个来自Central Cache的Span&#xff0c;根据Span的起始页的_pageId来对前一页所对应的Span进行查找&#xff0c;并判断该Span&#xff0c;是否处于使用状态&#xff0c;从而看是否可以合并&#xff0c;如果可以合并继续向前寻找。 当该Span前的空闲Span查…...

浅析JWT原理及牛客出现过的相关面试题

原文链接&#xff1a;https://kixuan.github.io/posts/f568/ 对jwt总是一知半解&#xff0c;而且项目打算写个关于JWT登录的点&#xff0c;所以总结关于JWT的知识及网上面试考察过的点 参考资料&#xff1a; Cookie、Session、Token、JWT_通俗地讲就是验证当前用户的身份,证明-…...

Spring AI (五) Message 消息

5.Message 消息 在Spring AI提供的接口中&#xff0c;每条信息的角色总共分为三类&#xff1a; SystemMessage&#xff1a;系统限制信息&#xff0c;这种信息在对话中的权重很大&#xff0c;AI会优先依据SystemMessage里的内容进行回复&#xff1b; UserMessage&#xff1a;用…...

【windows Docker desktop】在git bash中报错 docker: command not found 解决办法

【windows Docker desktop】在git bash中报错 docker: command not found 解决办法 1. 首先检查在windows中环境变量是否设置成功2. 检查docker在git bash中环境变量是否配置3. 重新加载终端配置4. 最后在校验一下是否配置成功 1. 首先检查在windows中环境变量是否设置成功 启…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...