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

暴力解法与其局限

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;
}
相关推荐
Hhy_11078 小时前
《C++深度解构06》手撕 string —— 从底层内存管理到深浅拷贝彻底吃透
c语言·开发语言·c++·学习·visual studio
青少儿编程课堂8 小时前
蓝桥杯青少组图形化省考报名倒计时·全国青少年信息素养大赛·电子学会图形化考级:校园黑白棋人机对战解析
c++·python·算法·bfs·信息学竞赛
YSL0701248 小时前
C++基础
开发语言·c++
eggwyw9 小时前
关于C++为什么不加入垃圾回收机制解析
开发语言·c++
jktantan9 小时前
注解式脱敏:用 Jackson 的 ContextualSerializer 做字段级策略(一)
spring boot·后端·算法·spring cloud·系统架构
曦樂~19 小时前
Cpp面筋
c语言·c++
道尔柯南19 小时前
C++ string 类详解:从常用接口到深拷贝,彻底掌握字符串处理
android·java·c++
Dream it possible!1 天前
LeetCode 面试经典 150_多维动态规划_交错字符串(97_C++_中等)
算法·leetcode·面试·动态规划
心抵鹊1 天前
算法之双指针系列(一)
算法·leetcode
十二1 天前
【洛谷题解】P1083 [NOIP 2012 提高组] 借教室(二分答案 + 差分)
数据结构·c++·算法·蓝桥杯