【优化算法:双指针算法刷题宝典】—— 盛最多水的容器

⚡ CYBER_PROFILE ⚡
/// SYSTEM READY ///


WARNING \]: DETECTING HIGH ENERGY **🌊 🌉 🌊 心手合一 · 水到渠成** ![分隔符](https://i-blog.csdnimg.cn/direct/60a3de2294e9439abad47378e657b337.gif) |------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------| | **\>\>\> ACCESS TERMINAL \<\<\<** || | [**\[ 🦾 作者主页 \]**](https://blog.csdn.net/fengtinghuqu520?spm=1000.2115.3001.5343) | [**\[ 🔥 C++初阶 \]**](https://blog.csdn.net/fengtinghuqu520/category_13085789.html) | | [**\[ 💾C++进阶 \]**](https://blog.csdn.net/fengtinghuqu520/category_13085793.html) | [**\[ 📡 代码仓库 \]**](https://blog.csdn.net/fengtinghuqu520/article/details/147275999?spm=1001.2014.3001.5502) | --------------------------------------- Running Process: 100% \| Latency: 0ms *** ** * ** *** #### 索引与导读 * [前言](#前言) * * [一、leetcode原题](#一、leetcode原题) * [二、题目分析](#二、题目分析) * * [2.1 关键点](#2.1 关键点) * [2.2 小编理解](#2.2 小编理解) * [三、算法设计思路](#三、算法设计思路) * * [3.1 利用 单调性 解决问题](#3.1 利用 单调性 解决问题) * [3.2 利用 双指针算法 解决问题](#3.2 利用 双指针算法 解决问题) * [3.3 \`不漏\` 问题](#3.3 `不漏` 问题) * [四、代码编写](#四、代码编写) * [💻结尾--- 核心连接协议](#💻结尾— 核心连接协议) ## 前言 本专栏深度聚焦**双指针算法** ,精准击破高频面试真题。不仅还原**算法原理** 与**解题思维** 的推演过程,更倾囊相授笔者的实战复盘笔记。**旨在通过典型案例拆解,助你构建由点及面的算法知识体系,高效攻克面试难关** ### 一、leetcode原题 > [🔗Lucy的空间骇客裂缝](https://leetcode.cn/problems/container-with-most-water/description/) ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/60edc786b1174b06a70ecc7dd516fdf1.png) *** ** * ** *** ### 二、题目分析 #### 2.1 关键点 * 核心任务 * **输入** :一个长度为 ( n ) 的整数数组 `height`。 * **几何模型**:坐标轴上有 ( n ) 条垂直线,第 ( i ) 条线的两个端点为 ((i, 0)) 和 ((i, height\[i\]))。 * **目标**:找出两条线,使得它们与 ( x ) 轴共同构成的容器可以容纳最多的水。 * **输出**:返回容器可以储存的最大水量 * 数学抽象 水量(即矩形的面积)由以下公式决定: A r e a = min ⁡ ( h e i g h t \[ i \] , h e i g h t \[ j \] ) × ( j − i ) Area = \\min(height\[i\], height\[j\]) \\times (j - i) Area=min(height\[i\],height\[j\])×(j−i) * 高度:受限于较短的那根柱子(木桶效应) * 宽度:两条柱子在 x x x 轴上的距离 ( j − i ) (j - i) (j−i)。 * 约束条件 * 不能倾斜容器。 * 数据规模: n n n 的范围是 \[ 2 , 10 5 \] \[2, 10\^5\] \[2,105\](这意味着 O ( n 2 ) O(n\^2) O(n2) 的暴力解法会超时,需要 O ( n ) O(n) O(n) 的优化算法) * h e i g h t \[ i \] height\[i\] height\[i\] 的范围是 \[ 0 , 10 4 \] \[0, 10\^4\] \[0,104

2.2 小编理解

由于以下公式决定容量: A r e a = min ⁡ ( h e i g h t [ i ] , h e i g h t [ j ] ) × ( j − i ) Area = \min(height[i], height[j]) \times (j - i) Area=min(height[i],height[j])×(j−i)

并且存在时间复杂度的限制,双循环算法必定超时

所以我们用常规的暴力枚举算法是无法解决的,这时我们优先引入双指针


三、算法设计思路

3.1 利用 单调性 解决问题

我们观察下面的数组:

[1,8,6,2,5,4,8,3,7]

  • 已知我们 容器的体积=底X高
  • 我们在数组首尾定义两个 "指针"
  • 再定义一个变量 存储最大的存储容量
  • 我们移动对向指针的时候, 肯定会减小
  • 如果我们移动 指向更大的数的指针
    • 这时候根据木桶效应 不变, 变小,所以总体积肯定会变小
  • 如果我们移动 指向更小的数的指针
    • 如果移向比原来更大的数,木桶的容量可能会上升,可能会下降
      • 如果下降,我们之前已经定义一个变量永远存储最大的容量
      • 如果上升,变量就会更新

简单来讲,你移动指向小的数的指针稳赚不赔,但是你移更大的数的指针绝对会亏损


3.2 利用 双指针算法 解决问题

我们在数组的首尾定义两个"指针 "

right的数比left大,left++

left的数比right大,right--

然后定义一个变量ret计算容器

再定义一个变量ans一直存储最大值


3.3 不漏 问题

初学者往往会担心:如果我移动了短板,会不会正好错过了那个"短板虽然短,但因为距离远而容量更大"的最优解?

这里有两个关键变量:

  1. 宽度 ( j − i j - i j−i):随着指针向中间移动,宽度必然减小
  2. 高度:由左右两板中的短板决定。

我们看图中的数组:

  • 当我们进行双指针移动后,来到这一步:

可能有初学者会疑惑:万一漏掉像height[0]height[4]的组合呢?它会不会比我们目前算法所存储的最大值还要大?

  • 在算法运行过程中确实可能不会被直接计算,但重点在于:算法已经提前通过逻辑证明了它不可能成为最大值

其实你担心漏掉像height[0]height[4]这样的组合,证明你没能完全理解木桶效应

当你的left1的时候,无论你的right怎么移动,它的宽度也只会不断减小,而高度已经固定了(1)

这时候以 h e i g h t [ 0 ] height[0] height[0] 为边界的所有组合,其最大潜力就是 5

那么,这个 h e i g h t [ 0 ] height[0] height[0] 就已经失去了利用价值


我们再以 h e i g h t [ 1 ] height[1] height[1] 为边界的所有组合,其最大的潜力就是与 h e i g h t [ 4 ] height[4] height[4] 相结合,而它已经被包含在内了


所以你会发现:这个算法的底层原理在于 将每个数的最优组合提取出来,从而避开炮灰组合,打造最佳时间复杂度


四、代码编写

cpp 复制代码
class Solution {
public:
    int maxArea(vector<int>& height) {
        // 定义基本的变量
        int n = height.size();
        int l = 0, r = n - 1;
        int ret = 0,ans = 0;
            while (l < r) {
                ret = (r - l)*min(height[r],height[l]);
                ans = max(ret,ans);
                if(height[l]<height[r]){
                    l++;
                }else{
                    r--;
                }
            }
            return ans;
        }
};

💻结尾--- 核心连接协议

警告: 🌠🌠正在接入底层技术矩阵。如果你已成功破解学习中的逻辑断层,请执行以下指令序列以同步数据:🌠🌠


【📡】 建立深度链接: 关注本终端。在赛博丛林中深耕底层架构,从原始代码到进阶协议,同步见证每一次系统升级。

【⚡】 能量过载分发: 执行点赞操作。通过高带宽分发,让优质模组在信息流中高亮显示,赋予知识跨维度的传播力。

【💾】 离线缓存核心: 将本页加入收藏。把这些高频实战逻辑存入你的离线存储器,在遭遇系统崩溃或需要离线检索时,实现瞬时读取。

【💬】 协议加密解密:评论区留下你的散列码。分享你曾遭遇的代码冲突或系统漏洞(那些年踩过的坑),通过交互式编译共同绕过技术陷阱。

【🛰️】 信号频率投票: 通过投票发射你的选择。你的每一次点击都在重新定义矩阵的进化方向,决定下一个被全量拆解的技术节点。



相关推荐
IT猿手2 小时前
多无人机动态避障路径规划研究:基于壁虎优化算法GJA的多无人机动态避障路径规划研究(可以自定义无人机数量及起始点),MATLAB代码
算法·matlab·无人机
listhi5202 小时前
MATLAB电力系统加权最小二乘法(WLS)状态估计
算法·matlab·最小二乘法
Epiphany.5562 小时前
树上dp问题
数据结构·算法
无籽西瓜a2 小时前
MD5算法原理、适用场景
java·后端·算法·哈希算法·md5
承渊政道2 小时前
【动态规划算法】(简单多状态dp问题入门与经典题型解析)
数据结构·c++·学习·算法·leetcode·macos·动态规划
南境十里·墨染春水2 小时前
C++笔记——STL map
开发语言·c++·笔记
fie88892 小时前
免疫优化算法在物流配送中心选址中的应用
算法·数学建模
南境十里·墨染春水2 小时前
C++笔记·-- STL unordered_map
开发语言·c++·笔记
珹洺2 小时前
C++远程调用组件库JsonRpc(一)项目背景、核心概念与环境搭建
开发语言·c++·rpc