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

【LeetCode 42】接雨水(单调栈、DP、双指针)

题面:

在这里插入图片描述

思路:

能接雨水的点,必然是比两边都低(小)的点。有两种思路,一种是直接计算每个点的最大贡献(也就是每个点在纵向上最多能接多少水),另一种就是计算每个点在横向上有没有贡献。
第一种思路,就需要我们能拿到每个点左右两边最高的高度,这样就能计算每个点在纵向上能接多少水,相当于木桶效应。
第二种思路,对于每个点,则需要判断它左右两边是不是都有比它高的点,每次计算横向上局部能接到水的区域。
官方题解挺好的,具体不再赘述

1. 单调栈

就是第二种思路,每次更新横向上能接到的水。

int trap(vector<int>& height) {int ans = 0, n = (int)height.size();stack<int> stk;for(int i = 0; i < n; ++ i) {while(!stk.empty() && height[i] > height[stk.top()]) {// 得到当前低点int buttom = stk.top(); stk.pop();if(!stk.empty()) {int j = stk.top();// 如果 height[j] == height[bottom]// 就说明 bottom 的左边还没有出现凸出来让bottom能接到水的边边ans += (i - j - 1) * (min(height[i], height[j]) - height[buttom]);}}stk.push(i);}return ans;
}

2. 动态规划

第一种思路,要拿到每个点左右两边的最大高度,就可以考虑线性DP的思想去记录当前点左右两边的最大高度。
l e f t M a x [ i ] = m a x ( l e f t M a x [ i − 1 ] , h e i g h t [ i ] ) r i g h t M a x [ i ] = m a x ( r i g h t M a x [ i + 1 ] , h e i g h t [ i ] ) g o t W a t e r [ i ] = m i n ( l e f t M a x [ i ] , r i g h t M a x [ i ] ) − h e i g h t [ i ] leftMax[i]=max(leftMax[i-1],height[i])\\ rightMax[i]=max(rightMax[i+1],height[i])\\ gotWater[i] = min(leftMax[i],\ rightMax[i])-height[i] leftMax[i]=max(leftMax[i1],height[i])rightMax[i]=max(rightMax[i+1],height[i])gotWater[i]=min(leftMax[i], rightMax[i])height[i]

int trap(vector<int>& height) {int ans = 0, n = (int)height.size();vector<int> leftMax(n), rightMax(n);leftMax[0] = height[0]; rightMax[n - 1] = height[n - 1];for(int i = 1; i < n; ++ i) leftMax[i] = max(leftMax[i - 1], height[i]);for(int i = n - 2; i >= 0; -- i) rightMax[i] = max(rightMax[i + 1], height[i]);for(int i = 1; i < n - 1; ++ i)ans += min(leftMax[i], rightMax[i]) - height[i];return ans;
}

双指针

使用双指针和临时变量优化掉 l e f t M a x leftMax leftMax r i g h t M a x rightMax rightMax 两个数组。
官方题解说:如果 h e i g h t [ l e f t ] < h e i g h t [ r i g h t ] height[left]<height[right] height[left]<height[right],则必有 l e f t M a x < r i g h t M a x leftMax<rightMax leftMax<rightMax
这主要是因为,我们每次移动的都是 h e i g h t height height 较小的指针,因此如果 l e f t M a x leftMax leftMax r i g h t M a x rightMax rightMax 有更新,则更新了的点 l e f t left left r i g h t right right l e f t M a x leftMax leftMax r i g h t M a x rightMax rightMax 得到新的更新之前会停留一阵子。因此如果 h e i g h t [ l e f t ] < h e i g h t [ r i g h t ] height[left]<height[right] height[left]<height[right],则必有 l e f t M a x < r i g h t M a x leftMax<rightMax leftMax<rightMax

int trap(vector<int>& height) {int ans = 0, n = (int)height.size();int left = 0, right = n - 1;int leftMax = height[0], rightMax = height[n - 1];while(left < right) {leftMax = max(leftMax, height[left]);rightMax = max(rightMax, height[right]);if(height[left] < height[right])ans += min(leftMax, rightMax) - height[left ++];elseans += min(leftMax, rightMax) - height[right --];}return ans;
}
http://www.xdnf.cn/news/342595.html

相关文章:

  • 日拱一卒 | RNA-seq数据质控(1)
  • ERC-20与ERC-721:区块链代币标准的双星解析
  • Spring MVC 中Model, ModelMap, ModelAndView 之间有什么关系和区别?
  • Spring AI Alibaba-04- Spring AI + RAG + ToolCalling 智能对话应用开发全流程
  • # 如何使用 PyQt5 创建一个简单的警报器控制界面
  • Linux基础(最常用基本命令)
  • 用kompose将docker-compose文件转换为K8S资源清单
  • WHAT - ahooks vs swr 请求
  • Qt获取CPU使用率及内存占用大小
  • 基于STM32、HAL库的CP2104 USB转UART收发器 驱动程序设计
  • Node.js 技术原理分析系列9——Node.js addon一文通
  • 【嵌入式面试高频知识点】-wifi相关
  • 钯铂贵金属分离回收树脂
  • 【写作格式】写论文时常见格式问题
  • sherpa-ncnn:Endpointing(断句规则)
  • 05_项目集成飞书预警
  • 浙大与哈佛联合开源图像编辑模型IC-Edit,实现高效、精准、快速的指令编辑~
  • 淘宝九宫格验证码识别
  • 【UltralyticsYolo11图像分类完整项目-02】onnx模型转engine格式+TensorRT版Gpu预测C++实现
  • 动态规划之两个数组的dp问题(最长公共子序列)
  • Unity图集系统(Sprite Atlas)
  • Vue实现不同网站之间的Cookie共享功能
  • 信息系统项目管理工程师备考计算类真题讲解十四
  • 【软件设计师:软件工程】9.软件开发模型与方法
  • Java三大基本特征之多态
  • auto_ptr和unique_ptr
  • 统一授权与加密防护,CodeMeter 护航机器视觉创新全链路
  • kafka logs storage
  • 日语学习-日语知识点小记-构建基础-JLPT-N4阶段(16):单词与句子
  • Element-ui Table tree 结构使用(解决无展开箭头)