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

LeetCode 42.接雨水

 题目描述  

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

示例

示例 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 个单位的雨水(蓝色部分表示雨水)。 

示例 2:

输入:height = [4,2,0,3,2,5]
输出:9

解法

1.双指针法
class Solution {
public:int trap(vector<int>& height) {// 处理空数组的情况if (height.empty()) return 0;// 初始化双指针:left指向最左边,right指向最右边int left = 0, right = height.size() - 1;// 记录左边和右边遇到的最大高度int left_max = 0, right_max = 0;// 存储最终的雨水总量int ans = 0;// 双指针向中间移动,直到相遇while (left < right) {// 如果左边高度小于右边高度,处理左指针if (height[left] < height[right]) {// 如果当前左边高度大于等于左边最大高度if (height[left] >= left_max) {// 更新左边最大高度(此时不能积水,因为这是新的最高点)left_max = height[left];} else {// 当前高度小于左边最大高度,可以积水// 积水量 = 左边最大高度 - 当前高度ans += left_max - height[left];}// 左指针向右移动left++;} else {// 如果右边高度小于等于左边高度,处理右指针// 如果当前右边高度大于等于右边最大高度if (height[right] >= right_max) {// 更新右边最大高度(此时不能积水)right_max = height[right];} else {// 当前高度小于右边最大高度,可以积水// 积水量 = 右边最大高度 - 当前高度ans += right_max - height[right];}// 右指针向左移动right--;}}// 返回最终计算的雨水总量return ans;}
};

        算法核心思想:对于每个位置,它能接的雨水量取决于它左右两边最高柱子中的较小值。当 height[left] < height[right] 时,说明左边的高度是限制因素,此时左边最大高度决定了当前位置能接多少雨水,右边的情况同理,双指针总是移动高度较小的一边,因为积水高度由较矮的一边决定。

2.动态规划法
class Solution {
public:int trap(vector<int>& height) {// 获取数组长度int n = height.size();// 处理空数组的情况if (n == 0) return 0;// 创建两个数组分别存储每个位置左边和右边的最大高度vector<int> left_max(n);  // left_max[i] 表示位置i左边的最大高度vector<int> right_max(n); // right_max[i] 表示位置i右边的最大高度// 计算每个位置左边的最大高度(从左往右遍历)left_max[0] = height[0]; // 第一个位置的左边最大高度就是它本身for (int i = 1; i < n; i++) {// 当前位置的左边最大高度 = max(前一个位置的左边最大高度, 当前高度)left_max[i] = max(left_max[i-1], height[i]);}// 计算每个位置右边的最大高度(从右往左遍历)right_max[n-1] = height[n-1]; // 最后一个位置的右边最大高度就是它本身for (int i = n-2; i >= 0; i--) {// 当前位置的右边最大高度 = max(后一个位置的右边最大高度, 当前高度)right_max[i] = max(right_max[i+1], height[i]);}// 计算总的雨水量int ans = 0;for (int i = 0; i < n; i++) {// 每个位置能接的雨水量 = min(左边最大高度, 右边最大高度) - 当前高度// 如果结果是正数就加入总量,负数则说明不能积水(取min会自动处理)ans += min(left_max[i], right_max[i]) - height[i];}// 返回最终计算的雨水总量return ans;}
};

           该算法核心思想分为三步。第一步,从左向右扫描,计算每个位置 i 左边的最大高度 left_max[i],left_max[i] = max(left_max[i-1], height[i])。第二步,从右向左扫描,计算每个位置 i 右边的最大高度 right_max[i],right_max[i] = max(right_max[i+1], height[i])。第三步,计算每个位置的积水量,对于每个位置 i,积水高度 = min(left_max[i], right_max[i]) - height[i],将所有位置的积水量相加得到总和。

http://www.xdnf.cn/news/1358749.html

相关文章:

  • response对象的elapsed属性
  • Elasticsearch Ruby 客户端故障排查实战指南
  • Bright Data MCP:突破AI数据获取限制的革命性工具
  • 阿里云 OSS 前端直传实战:表单上传 + Policy 模式详解
  • GD32VW553-IOT 测评和vscode开发环境搭建
  • 硬件开发_基于物联网的宠物猫饲养系统
  • 互联网大厂Java面试模拟:核心技术点深度解析
  • 极验demo(float)(二)
  • 从字节码层面剖析以太坊智能合约创建原理
  • EXCEL实现复制后倒序粘贴
  • 从Android到鸿蒙:一场本应无缝的转型-优雅草卓伊凡
  • iptables 防火墙核心知识梳理(附实操指南)
  • 【文献阅读】Land degradation drivers of anthropogenic sand and dust storms
  • 《一次高并发场景下疑难Bug的深度排查与复盘》
  • rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(十七)设置主题
  • AI代码生成器全面评测:六个月、500小时测试揭示最强开发助手
  • CI/CD持续集成及持续交付详解
  • 户外广告牌识别误报率↓79%!陌讯多模态融合算法在城市广告合规监测的实战解析
  • TEE-可信执行环境
  • 程序里的依赖和中间件的依赖冲突,怎么解决
  • C++20: std::span
  • 多线程下单例如何保证
  • elasticsearch 7.x elasticsearch是查询的数据量大于10000分页有问题还是es的库总量大于10000分页有?
  • 【软件安全】ARM64、x86、32 位与 64 位架构的区别、定义、应用背景
  • 安装gitlab
  • Dify 从入门到精通(第 53/100 篇):Dify 的分布式架构(进阶篇)
  • 线程整理文档
  • git学习
  • Wagtail CRX 的 Latest Pages Block 高级设置 模版v3.0 以后被阉割了
  • Vue vs React:前端框架的差异与选择