Leetcode(11)盛最多水的容器——双指针&&为什么不会错过最优解

题目描述
给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。
在这里插入图片描述
示例:

  • 输入: [1,8,6,2,5,4,8,3,7]
  • 输出: 49
思路

一开始本着动规的思想试图建立状态方程,发现状态数太多,并且状态间并不会有转移的过程,故弃。
容器与两个因素有关:1.底边长 2.短边高度 ,设左右两个指针 i j,分别扫描。一直移动短边,即 i高度 < j时, i 右移 ; i 高度 > j 时,j 左移。

代码
class Solution {
public:
    int maxArea(vector<int>& height) {
        int maxArea = 0,l = 0,r = height.size() - 1;
        while(l < r){
                maxArea = max(maxArea,min(height[l],height[r]) * (r - l));
                if(height[l] < height[r]){
                    l++;
                }
                else
                    r--;
        }
        return maxArea;

    }
};

为什么不会错过最优解?

当前容积为A = (j - i) * min( h(i),h(j) ),因为短边是容积的影响因素,所以如果长边的下一个更长,移动长边,对容积没有影响。如果下一个更短,一定不是最优解。移动短边才会出现最优解。

虽然移动矮指针以后会可能出现更大的面积,从而放弃了移动高的指针,但是没准虽然现在 移动高的指针不能增加但是以后以这个为基准会演变出最大的面积?

我们担心如果高指针 j 的下一个 n 更高,不移动 j 会不会错过这个n边。也就是说,我们会错过i 到 n之间的一段面积,而这个面积会成为最大值?
假设目前状况如下:
在这里插入图片描述

假设 i ~ n 间存在一个 m ,使得 m ~n的面积最大.

  1. H m &lt; = H j H_m &lt;= H_j Hm<=Hj时:
    m n mn mn 的面积一定小于等于 m j mj mj m n mn mn并不是最大值,与题设不符。
    在这里插入图片描述
  2. H m &gt; H j H_m &gt; H_j Hm>Hj
    低指针 i 移动到 m 时,因为 H m &gt; H j H_m &gt; H_j Hm>Hj,所以高指针此时变为m,j指针一定会向左移动至n,不会错过这个解(无论 H n H_n Hn H m H_m Hm的关系如何)。
    在这里插入图片描述
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值