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

02 相向双指针

03 乘最多水的容器

image
image
image

3.1 思考

考虑这条短的红线,它和中间的线构成容器,分类讨论

  • 如果中间的线比它短,宽度减少,高度减少
  • 如果中间的线比它长,宽度减少,高度不变
    因此,中间的任何一条线和它构成新的容器,都无法容纳更多的水。
    所以要想容纳更多的水,就需要移动短的这条线。

3.2 实现

点击查看代码
class Solution {
public:int maxArea(vector<int>& height) {int n = height.size();int left = 0, right = n - 1;int ans = 0;while (left < right) {int h = min(height[left], height[right]);ans = max(ans, (right - left) * h);if (height[left] < height[right]) {++left;} else {--right;}}return ans;}
};
- 时间复杂度:$$O(n)$$ - 空间复杂度:$$O(1)$$

04 接雨水

image
image

4.1 思考

假设对于每个位置都有1个宽度为1的桶,那这个桶能接多少水,就取决于左右两边木板的高度。
对于一个桶而言,它左边木板的高度,取决于左边柱子的最大高度。

4.2 两种做法

4.2.1 计算前后缀

需要用到两个额外的数组。
对于第i个桶,一个数组记录0~i的柱子的最大高度(前缀的最大值),一个数组记录i~n-1的柱子的最大高度(后缀的最大值)。

这里可能有点疑惑,为什么针对前后缀,还要和i比较呢?
我们可以理解为对于第i个桶而言,第i个位置放置的石块height[i]就是在这个桶两边的木板高度。

举个例子,假如height[i]=3,这是前后缀的最大值。那么这个桶理论上可以装3个单位的水,但是结果现在这个桶装了3块石头,所以可容纳的水为0。

点击查看代码
class Solution {
public:int trap(vector<int>& height) {int n = height.size();vector<int> suf_max(n); // 后缀最大值// 对于第i个木桶,它的后缀最大值为[i, n - 1]suf_max[n - 1] = height[n - 1];for (int i = n - 2; i >= 0; --i) {suf_max[i] = max(height[i], suf_max[i + 1]);}int ans = 0, pre_max = height[0];for (int i = 1; i < n; ++i) {pre_max = max(pre_max, height[i]); // 更新前缀最大值ans += min(suf_max[i], pre_max) - height[i];}return ans; }
};
  • 时间复杂度:$$O(n)$$
  • 空间复杂度:$$O(n)$$

其实,我本来也不太理解为什么前后缀还要包含第i个位置呢?但是现在我发现其实不包含第i个位置也能做,

点击查看代码
class Solution {
public:int trap(vector<int>& height) {int n = height.size();vector<int> suf_max(n, 0); // 后缀最大值// 对于第i个木桶,它的后缀最大值为[i + 1, n - 1]suf_max[n - 1] = 0; // 不可能接到水for (int i = n - 2; i >= 0; --i) {suf_max[i] = max(height[i + 1], suf_max[i + 1]);}int ans = 0, pre_max = 0;for (int i = 1; i < n; ++i) {pre_max = max(pre_max, height[i - 1]);int h = min(suf_max[i], pre_max);ans += (h - height[i] < 0) ? 0: h - height[i];   }return ans; }
};

4.2.2 相向双指针

一个木桶能接多少水,和它左右两边的木板高度(前缀最大值和后缀最大值)有关。
注意:前缀最大值(顺序遍历)和后缀最大值(倒序遍历)是不会变小的。
那么,假如我们顺序遍历,已经知道了当前木桶的前缀最大值,后缀最大值虽然不知道,但是可以用一个指针指向最后一个元素的后缀最大值,假如是1。分类讨论:

  • 前缀最大值 < 后缀最大值,能接多少水取决于前缀最大值;
  • 同理,如果后缀最大值 < 前缀最大值,那么能接多少水取决于后缀最大值。
    终于悟了。
点击查看代码
class Solution {
public:int trap(vector<int>& height) {// 相向双指针int n = height.size();int left = 0, right = n - 1;int ans = 0, pre_max = 0, suf_max = 0;while (left < right) {pre_max = max(pre_max, height[left]);suf_max = max(suf_max, height[right]);if (pre_max < suf_max) {ans += pre_max - height[left];++left;  } else {ans += suf_max - height[right];--right;}}return ans;}
};
- 时间复杂度:$$O(n)$$ - 空间复杂度:$$O(1)$$
http://www.rkmt.cn/news/114626.html

相关文章:

  • Blender建筑建模终极指南:building_tools插件快速上手
  • 2025年成都桥架厂家权威推荐榜单:锌铝镁桥架/201不锈钢桥架/工地不锈钢桥架源头厂家精选 - 品牌推荐官
  • 扫描频率决定安全性?,深度解析Docker Scout自动扫描机制与风险盲区
  • OOP-实验6
  • 医疗和教育行业自动化、精准匹配、易掌握的数据分类分级最佳实践与案例
  • 毕设 深度学习yolo藻类细胞检测识别(科研辅助系统)(源码+论文)
  • RAG知识库构建策略
  • C++中的共用体与枚举:内存优化与类型安全
  • 2025年下半年鄂尔多斯车牌识别供应商推荐榜单 - 2025年品牌推荐榜
  • 2025年12月单股加固型网带,双股加固型网带,链式网带厂家品牌推荐榜,彰显国产技术实力 - 品牌鉴赏师
  • 【高可用架构必备技能】:Docker Offload中任务状态同步的7种最佳实践
  • 【Docker-LangGraph Agent配置终极指南】:掌握高效AI代理部署的5大核心技巧
  • HCA解码器完整教程:快速转换游戏音频的终极方案
  • 从零构建智能监控体系,基于Agent的Docker告警实战详解
  • Mem Reduct终极内存优化:三步让老电脑重获新生
  • Mem Reduct内存管理工具:系统性能优化实战指南
  • 15、网页数据处理与自动化操作实用指南
  • JRebel 激活失效?手把手教你本地搭建激活服务器(无需公网、无需 Docker)
  • 终极自适应解决方案:autofit.js一键实现完美大屏适配
  • 【读书笔记】《孙子兵法》
  • 谷歌关停暗网监控工具:2026年安全防护迎来“精准化”转型
  • 18、利用 SSH 实现安全的远程访问
  • Pearcleaner Homebrew管理:3步告别复杂命令行操作
  • 国产算力崛起背景下,大模型训练数据集的 “采洗之道”:技术实践与效率优化
  • 有源逻辑探头的具体应用
  • 高并发下,TPS/QPS/并发数这三者的区别?
  • 基于WPF的半导体设备配方管理程序技术方案
  • 半导体行业ALD阀技术路线分析及解决方案教程
  • Delphi中循环删除记录的实现方法
  • 16、远程系统管理与安全设置全攻略