【LeetCode刷题笔记(8-3)】【Python】【接雨水】【双指针】【困难】

news2024/9/30 3:31:03

文章目录

  • 引言
  • 接雨水
    • 题目描述
    • 提示
  • 解决方案3:【双指针】
  • 结束语

接雨水

【LeetCode刷题笔记(8-1)】【Python】【接雨水】【动态规划】【困难】

【LeetCode刷题笔记(8-2)】【Python】【接雨水】【单调栈】【困难】

引言

编写通过所有测试案例的代码并不简单,通常需要深思熟虑理性分析。虽然这些代码能够通过所有的测试案例,但如果不了解代码背后的思考过程,那么这些代码可能并不容易被理解和接受。我编写刷题笔记的初衷,是希望能够与读者们分享一个完整的代码是如何在逐步的理性思考下形成的。我非常欢迎读者的批评和指正,因为我知道我的观点可能并不完全正确,您的反馈将帮助我不断进步。如果我的笔记能给您带来哪怕是一点点的启示,我也会感到非常荣幸。同时,我也希望我的分享能够激发您的灵感和思考,让我们一起在编程的道路上不断前行~

接雨水

题目描述

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

在这里插入图片描述
图片来源

提示

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105

解决方案3:【双指针】

在【LeetCode刷题笔记(8-1)】【Python】【接雨水】【动态规划】【困难】和【LeetCode刷题笔记(8-2)】【Python】【接雨水】【单调栈】【困难】中,我们详细阐述了如何在一步步理性分析下基于【动态规划】和【单调栈】设计完整的算法和代码通过接雨水的所有测试用例。这两种算法的空间复杂度都是O(n),其中动态规划法需要额外维护两个长度为N的数组left_max_listright_max_list,用于记录每个位置i ,其左侧柱子的最大高度left_max_list[i]和右侧柱子的最大高度right_max_list[i]

具体来说,我们首先从左到右完整地遍历数组height得到left_max_list,然后再从右往左完整地遍历数组height得到right_max_list。实际上,这相当于把【接雨水】问题的解决策略分成两个相对独立的步骤:

  1. 获取每个位置i ,其左侧和右侧柱子的最大高度。这一步需要两个for循环,分别从左到右和从右到左遍历数组。

  2. 根据木桶原理,以及步骤1获取的必要信息,得到最终的雨水总量。这一步还需要一个for循环,遍历整个数组。

问题1:有没有其它策略能够把步骤一和步骤二结合起来,即在一个循环下解决【接雨水】问题?

有,双指针。

在上面的分析过程中,我们发现步骤1的两个循环,一个是从左往右,一个是从右往左,这种遍历方法和双指针非常类似。因此,我们考虑是否可以用左指针替代从左往右的循环,同时用右指针替代从右往左的循环。这样,我们可以在一次遍历中完成两个步骤,提高算法的效率。

不仅可以,而且还买一送一,顺带解决了获取位置i雨水量的问题。

1. 当左指针left从左往右的移动过程中,我们可以通过left_max记录区间[0,left]的最大高度 。同理,当右指针right从右往左的移动过程中,我们也可以通过right_max记录区间[right,n-1]的最大高度。

关键问题2:如何决定下一步是移动左指针还是右指针?

当能确定位置left的接水量时,left右移;当能确定位置right的接水量时,right左移;

对于当前左指针的位置left,[0, left]区间的最大高度left_max是已知的,并且[right,n-1]区间的最大高度right_max也是已知的。根据木板原理,一个木桶的装水量总是受限于其最短的那块木板 ⇒ 此时left_max<right_max成立 ⇒ [0, left]的最高左木板 < [right, n-1]区间的最高右木板 <= [left+1, n-1]区间的最高右木板 恒成立⇒ 位置left的装水量由[0, left]的最高左木板决定,而[0, left]的最高左木板已经是板上钉钉 ⇒ 自然可以计算位置left的接水量water_left = left_max - height[left];既然位置left的接水量已经确定,下一步自然是left右移。

同理,对于当前右指针的位置right,[0, left]区间的最大高度left_max是已知的,并且[right,n-1]区间的最大高度right_max也是已知的 ⇒ 此时right_max < left_max成立 ⇒ [right, n-1]区间的最高右木板 < [0, left]的最高左木板 <= [0,right-1]区间的最高左木板 恒成立⇒ 位置right的装水量由 [right, n-1]区间的最高右木板决定,而 [right, n-1]区间的最高右木板的值已经是板上钉钉 ⇒ 自然可以计算位置right的接水量water_right = right_max - height[right];既然位置right的接水量已经确定,下一步自然是right左移。

完整代码如下

class Solution:  
    def trap(self, height: List[int]) -> int:  
        # 初始化结果为0  
        total_water = 0  
        # left指向数组的起始位置  
        left = 0  
        # right指向数组的末尾位置  
        right = len(height) - 1  
        # left_max记录从左到left的最大高度  
        left_max = 0  
        # right_max记录从right到数组末尾的最大高度  
        right_max = 0  
    
        # 当left小于right时,持续进行以下操作  
        while left < right:  
            # 更新left_max为当前left位置的高度和left_max中的较大值  
            left_max = max(left_max, height[left])  
            # 更新right_max为当前right位置的高度和right_max中的较大值  
            right_max = max(right_max, height[right])  
                
            if left_max < right_max:  
                # left_max小于right_max ==> 依据木桶原理 ==> 位置left雨水量由左木板最大高度和位置left的柱子高度共同确定  
                total_water += left_max - height[left]  
                # 向右移动left  
                left += 1  
            else:  
                # right_max大于等于left_max ==> 依据木桶原理 ==> 位置right的雨水量由左木板最大高度和位置left的柱子高度共同确定  
                total_water += right_max - height[right]  
                # 向左移动right  
                right -= 1  
            
        # 返回最终的雨水量  
        return total_water

运行结果
在这里插入图片描述

复杂度分析

  • 时间复杂度:O(N),其中 N 是数组height元素的数量。
  • 空间复杂度:O(1)
    • 利用双指针动态记录区间[0, left] 和[right, N-1]的最大值 ===> O(1)

结束语

  • 亲爱的读者,感谢您花时间阅读我们的博客。我们非常重视您的反馈和意见,因此在这里鼓励您对我们的博客进行评论。
  • 您的建议和看法对我们来说非常重要,这有助于我们更好地了解您的需求,并提供更高质量的内容和服务。
  • 无论您是喜欢我们的博客还是对其有任何疑问或建议,我们都非常期待您的留言。让我们一起互动,共同进步!谢谢您的支持和参与!
  • 我会坚持不懈地创作,并持续优化博文质量,为您提供更好的阅读体验。
  • 谢谢您的阅读!

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

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

相关文章

MySQL数据库:表的约束

目录 一. 空属性null 二. 默认值default 三. 列描述comment 四. 填充零zerofill 五. 主键primary key 六. 自增长auto_increment 七. 唯一键unique 八. 外键foreign key 一. 空属性null 对于表中的数据&#xff0c;如果在进行插入的时候不显示地给定值&#xff0c;那么…

RabbitMQ入门指南(一):初识与安装

专栏导航 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、消息队列介绍 1.同步调用和异步调用 2.常见消息队列介绍 二、RabbitMQ简介及其安装步骤 1.RabbitMQ简介 2.RabbitMQ安装步骤&#xff08;使用Docker&#xff09; (1) 创建网络 (2) 使用Docker来…

文件上传——后端

文件上传流程&#xff1a; 创建阿里云OSS&#xff08;对象存储服务&#xff09;的bucket 登录阿里云&#xff0c;并完成实名认证&#xff0c;地址&#xff1a;https://www.aliyun.com/. 可以通过搜索&#xff0c;进入以下页面&#xff1a; 点击立即使用后&#xff1a; 点击…

Spring Boot3.1.6配置对应的Swagger

1. pom.xml导入Swagger依赖 <!--swagger3--> <dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.0.2</version> </dependency> 2.创建SwaggerCo…

【兔子王赠书第13期】AI绘画实战:Midjourney从新手到高手

文章目录 写在前面AI绘画推荐图书一本书读懂AI绘画关键点内容简介作者简介 推荐理由粉丝福利写在后面 写在前面 如今AI技术已经进入了我们的日常学习生活中&#xff0c;如何用一本书轻松玩转AI绘画&#xff0c;领略无限艺术可能呢&#xff1f; AI绘画 AI绘画是指利用人工智能…

麒麟V10 ARM内核aarch64 安装harbor redis 存储错误解决办法

安装harbor 里面自带的 redis 报错 “jemalloc: Unsupported system page size” 解决办法 下载指定镜像的redis 替换harbor 自带的redis镜像 修改 docker-compose 文件替换原来的镜像版本。 删除 重构镜像执行&#xff1a; docker-compose up –build 后台启动&#xff…

Ubuntu 常用命令之 apt-get 命令用法介绍

apt-get是Ubuntu系统下的一个命令行工具&#xff0c;用于处理包。这个命令可以自动下载和安装软件包及其依赖项。它是Advanced Packaging Tool (APT)的一部分&#xff0c;APT是处理包的高级工具&#xff0c;可以处理复杂的包关系&#xff0c;如依赖关系等。 apt-get命令的常见…

〖Python网络爬虫实战㊸〗- 极验滑块介绍(五)

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;订阅本专栏前必读关于专栏〖Python网络爬虫实战〗转为付费专栏的订阅说明作者&#xff1…

调用第三方http接口 hutool工具类

1、引入依赖 <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.0.M2</version> </dependency>2、请求组装 String params"<BSXml>" " <MsgHeader>&…

【Java并发】聊聊线程的几种状态

线程状态 线程的状态 在Thread中有一个枚举类进行标识 /*** 线程状态** NEW 尚未启动的线程处于这种状态* RUNNABLE 在 JVM 上执行的线程处于这种状态* BLOCKED 被阻止等待监视器锁的线程处于这种状态* WAITING 即无限期地等待另一个线程来执行某一特定操作的线程处于这种状态…

Sectigo dv通配符ssl证书

DV通配符SSL证书是数字证书中比较特别的一款&#xff0c;这款SSL数字证书能同时为多个域名网站提供安全加密服务&#xff0c;帮助个人或者企事业单位获得主流浏览器以及终端的认可&#xff0c;从而营造良好的互联网环境。今天就随SSL盾小编了解Sectigo旗下的DV通配符SSL证书。 …

【Linux基础】1. Linux 启动过程

文章目录 【 1. 内核的引导 】【 2. 运行init 】 运行级别 【 3. 系统初始化 】【 4. 建立终端 】【 5. 用户登录系统 】【 6. 图形模式与文字模式的切换方式 】【 7. Linux关机 】 Linux系统的启动过程分为 5个阶段&#xff1a; &#xff08;1&#xff09;内核的引导。 &#…

Android修改submodule的lib包名

一、正常使用submodule的流程 在指定路径下&#xff1a; git clone gitgit.youraddress.com:android-apps/taobao.git cd taobao/ git checkout develop git submoudle init git submodule update二、改名步骤 需求&#xff1a;将LibStat改为libStat 因为Linux对大小写敏感…

国家开放大学 河南开放大学形成性考核 平时作业 统一参考资料

试卷代号&#xff1a;1258 房屋建筑混凝土结构设计 参考试题 一、单项选择题&#xff08;每小题2分&#xff0c;共计40分&#xff09; 1.( )是将框架结构中的部分跨间布置剪力墙或把剪力墙结构的部分剪力墙抽掉改为框架承重。 A.梁板结构体系 B.框…

银行数据分析进阶篇:银行业零售贷款营销与风控平衡分析

上周和大家分享了银行外呼数据分析与客户精准营销的案例&#xff0c;得到很多朋友正向的反馈&#xff0c;今天再次给大家带来银行业零售贷款营销与风控平衡分析的案例&#xff0c;结构清晰&#xff0c;可直接复制套用&#xff0c;特地分析给大家&#xff01; 本文主要分享作者分…

车载软件易受攻击,如何规避嵌入式软件漏洞

在汽车开发中&#xff0c;汽车网络安全至关重要&#xff0c;特别是现在汽车软件变得日益互联。阅读本文&#xff0c;了解如何预防汽车网络安全漏洞。 为什么汽车网络安全很重要&#xff1f; 如今&#xff0c;互联汽车的解决方案远不只有简单的从A点到B点。通过实时数据共享、应…

【数值计算方法】《工程数值计算Python教程》笔记

文章目录 [toc]第一章&#xff1a;绪论 1.1 1.1 1.1|数值计算在工程科学中的重要性 1.2 1.2 1.2|数值计算方法 1.3 1.3 1.3|程序设计盒图计算方法的选取减少运算次数避免相近的数相减 1.4 1.4 1.4|误差的来源、表示及传递误差的来源和分类模型误差观测误差截断误差舍入误差 误差…

力扣日记12.19-【二叉树篇】二叉搜索树中的搜索

力扣日记&#xff1a;【二叉树篇】二叉搜索树中的搜索 日期&#xff1a;2023.12.19 参考&#xff1a;代码随想录、力扣 700. 二叉搜索树中的搜索 题目描述 难度&#xff1a;简单 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和一个整数值 val。 你需要在 BST 中…

微软在 Perforce Helix 核心服务器中发现4个安全漏洞

微软分析师在对Perforce Helix的游戏开发工作室产品进行安全审查时&#xff0c;发现为游戏、政府、军事和技术等部门广泛使用的源代码管理平台 Perforce Helix Core Server 存在四大漏洞&#xff0c;并于今年 8 月底向 Perforce 报告了这些漏洞&#xff0c;其中一个漏洞被评为严…

HarmonyOS应用开发实战—开箱即用的活动创建页面【ArkTS】【鸿蒙专栏-33】

一.HarmonyOS应用开发实战—开箱即用的个人主页页面【ArkTS】【鸿蒙专栏-32】 1.1 项目背景 HarmonyOS(鸿蒙操作系统)是华为公司推出的一种分布式操作系统。它被设计为一种全场景、全连接的操作系统,旨在实现在各种设备之间的无缝协同和共享,包括智能手机、平板电脑、智能…