双指针算法:最大盛水容器

暴力解法与其局限

11. 盛最多水的容器 - 力扣(LeetCode)

此题简单来说,就是给了一个数组,我们要将数组元素的值作为"墙",下标的距离为底,围成一个水缸,求得容积最大的那个。

先说暴力解法。

这很简单,容积等于底乘以高,给两个指针,依次遍历所有组合,依次求容积,每次更新容积最大的那个即刻,代码如下:

cpp 复制代码
int maxArea_bad(vector<int>& height) {
    //遍历组合
    int n = height.size();
    int v = 0;
    for (int i = 0; i < n; i++)
    {
        for (int j = i + 1; j < n; j++)
        {
            int w = j - i;//宽度
            int h = height[i] > height[j] ? height[j] : height[i];//高度
            if (v <= w * h)
            {
                v = w * h;
            }
        }
    }
    return v;
}

它的局限很明显------许多可排除的组合它都进行了遍历。

我们拿一个示例:

cpp 复制代码
h = [2, 8, 6, 2, 5, 4, 8, 3, 7]
     0  1  2  3  4  5  6  7  8

left此刻在0处,我们移动另一个指针right。

这时,你会发现,八个组合,每次用于计算的高都是left处的1,导致这些组合都被淘汰,原因很简单:容积的高受较矮的那个影响。

发现了这个就很好办了。

双指针优化

我们干脆把两个指针安排在两边,计算完了容积后,让较矮的那个移动往中间靠拢,不断更新容积。

比如组合(2,7)计算完后,更新更小的左边,left++,直接从(8,7)开始,因为如果计算(2,7)之间,底只会更短,而更新7那一边的话,就没有意义。比如,如果新的右边比左边更小,那容积会更小,如果比左边更大,那高度还是会依据左边。

这样一来,代码显而易见:

cpp 复制代码
int maxArea(vector<int>& height)
{
    int left = 0, right = height.size() - 1;
    int w = 0;//宽
    int v = 0;//体积
    while (left < right)
    {
        w = right - left;
        if (height[left] < height[right])
        {
            if (v < w * height[left])
            {
                v = w * height[left];
            }
            left++;
        }
        else
        {
            if (v < w * height[right])
            {
                v = w * height[right];
            }
            right--;
        }
    }

    return v;
}

当然,我们可以使用更加简洁的写法:

cpp 复制代码
int maxArea_better(vector<int>& height)
{
    int left = 0, right = height.size() - 1, ret = 0, v = 0;
    while (left < right)
    {
        v = (right - left) * (height[left] < height[right] ? height[left++] : height[right--]);
        ret = max(ret, v);
    }
    return ret;
}
相关推荐
草莓熊Lotso1 小时前
【C++ 基于微服务的即时通讯系统】etcd + brpc 从安装到服务注册发现全链路实战
网络·数据库·c++·redis·微服务·etcd
HPtiger7 小时前
数据结构——选择排序
数据结构·算法·排序算法
康实训7 小时前
老年评估仿真实训平台架构设计与老年人能力评估实训室教学落地实践
大数据·人工智能·算法·实训室·实训室建设
DongQiShanRen7 小时前
六根硬件映射(四):归属澄清、两处不一致与卷十一总表
开发语言·人工智能·算法·rust·哈希算法·集成学习
CCblandy7 小时前
雪花 ID 四个边界实测:时钟回拨重号 500 个,前端 JSON.parse 直接丢精度
后端·python·算法·性能优化·架构
丑梨数据7 小时前
信创环境里跑文档工具:格式兼容与本地合规的几个坑
数据结构·人工智能·算法·决策树·排序算法
把我格子衫拿来8 小时前
VTK 9.5 与 Qt 6 联合开发:从嵌入三维窗口到可维护的桌面架构
c++·python·qt·vtk·三维可视化
无忧.芙桃8 小时前
C++语言原理与实践(十六):多态机制讲解
开发语言·c++·多态
erzong2319 小时前
Linux操作系统:线程概念与控制
linux·算法
wuminyu10 小时前
JMM学习总结:深入理解happens-before关系
java·linux·c语言·jvm·c++