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

10.接雨水

在这里插入图片描述


✅ 解法一:双指针法(推荐)

⭐ 时间复杂度:O(n),空间复杂度:O(1)

🌟 思路

左右指针从两边向中间移动,维护左右两边的最大值,用较小一边的最大值判断当前能接多少水。

💡 C++ 代码

class Solution {
public:int trap(vector<int>& height) {int left = 0, right = height.size() - 1;int leftMax = 0, rightMax = 0;int total = 0;while (left < right) {if (height[left] < height[right]) {if (height[left] >= leftMax) {leftMax = height[left];  // 更新左侧最大高度} else {total += leftMax - height[left];  // 计算当前位置能接的水}++left;} else {if (height[right] >= rightMax) {rightMax = height[right];  // 更新右侧最大高度} else {total += rightMax - height[right];  // 接水}--right;}}return total;}
};

✅ 解法二:动态规划法(前缀+后缀最大值预处理)

⭐ 时间复杂度:O(n),空间复杂度:O(n)

🌟 思路

对每个位置计算「左边最大值」和「右边最大值」,然后计算该位置能接多少水。

💡 C++ 代码

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

✅ 解法三:单调栈

⭐ 时间复杂度:O(n),空间复杂度:O(n)

🌟 思路解析:

我们维护一个单调递减栈,栈中存放的是下标索引。当我们遇到一个比栈顶元素高的柱子时,说明形成了一个可接雨水的凹槽结构,这时候计算能接多少水。

📌 举个例子:
  • 当前柱子是右墙;
  • 栈顶元素是低洼地(bottom);
  • 栈下一个元素是左墙;
  • 用左、右墙的最小高度减去底部高度,即为这段的雨水量。

💡 C++ 代码 + 注释

class Solution {
public:int trap(vector<int>& height) {int n = height.size();stack<int> st;  // 存储下标int total = 0;for (int i = 0; i < n; ++i) {// 当前柱子比栈顶高,说明可以形成凹槽while (!st.empty() && height[i] > height[st.top()]) {int bottom = st.top();st.pop();if (st.empty()) break;  // 没有左边界,不能接水int left = st.top();int width = i - left - 1;  // 左右柱子之间的宽度int heightBound = min(height[left], height[i]) - height[bottom];  // 能装的水高total += width * heightBound;  // 计算雨水量}st.push(i);  // 当前柱子入栈}return total;}
};

✅ 三种主流解法对比总结:

解法时间复杂度空间复杂度是否推荐特点
双指针O(n)O(1)✅ 最推荐思路直观、代码简洁
动态规划O(n)O(n)✅ 推荐易理解、适合初学
单调栈O(n)O(n)✅ 拓展适合强化数据结构理解

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

相关文章:

  • 九、【ESP32开发全栈指南: UDP通信服务端】
  • Redis 持久化机制深度解析
  • 反向传播的核心是什么:计算损失函数对可训练参数的梯度=== 损失函数能通过计算图连接到可训练参数
  • 打印高质量日志的10条军规
  • FPGA 可重构技术的实现方法
  • 技术有边界,责任无止境——AI伦理治理的未来挑战与全球路径
  • Welearn 課程時長半小時速刷200小時油猴腳本
  • 类与对象(1)
  • 物联网技术发展与应用研究分析
  • 技巧小结:根据寄存器手册写常用外设的驱动程序
  • 6.7-leetcodeT3170
  • 低成本嵌入式Linux开发方案:RV1106入门
  • 代码注释类型
  • 【win | 自动更新关闭】win11
  • 解决使用nvm安装node报错或者安装后有node没有npm
  • 基于投影寻踪博弈论-云模型的综合评价
  • 设计一套流程引擎队列分发器
  • 2025年AI编程工具推荐
  • 外部排序全解析:从基础到优化策略(王道)
  • go工具库:hertz api框架 hertz client的使用
  • 无线网络扫描与分析工具 LizardSystems Wi-Fi Scanner 25.05
  • 【python深度学习】Day 47 注意力热图可视化
  • 蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析
  • transformers 的Trainer的用法
  • Cloudflare 免费域名邮箱 支持 Catch-all 无限别名收件
  • JAVA理论第四战-线程池
  • 【AI论文】反思、重试、奖励:通过强化学习实现大型语言模型的自我提升
  • archlinux中使用 Emoji 字体
  • keil 5打开编译keil 4解决方案,兼容exe查找下载
  • 编程关键字