leetcode 11 盛最多水的容器

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

说明:你不能倾斜容器。

示例 1:
在这里插入图片描述
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例 2:

输入:height = [1,1]
输出:1
示例 3:

输入:height = [4,3,2,1,4]
输出:16
示例 4:

输入:height = [1,2,1]
输出:2

提示:

n = height.length
2 <= n <= 3 * 104
0 <= height[i] <= 3 * 104

思路分析:
双指针法,第一次做本题时,如何使用双指针不容易想出,需要多做题见过更多题才能更容易有思路。
本题的双指针思路是:刚开始双指针指向左右边界,分别为l,r,t = r - l , 那么当前这个ans就是 min(h[l],h[r])*t,然后选择移动高度值较小的那边的指针,向中间移动,然后计算ans,进行更新,直到l和r相遇即可,ans就是答案。
为什么这样每次移动高度较小的那边的指针的思路是正确的,进行证明:
设当前指针为,l,r,且h[l] < h[r], t = l - r,当前对应的ans为 min(h[l],h[r])*t = h[l] *t。
如果我们此时移动高度较高的那一边指针,它的ans总是小于等于上一个ans,我们可以进行证明
若r 向左移动,当前为r1,t1 = r1 - l < t
此时的h[r1]和h[l]比较分为两种情况
1.h[r1] > h[l],那么当前ans = min(h[r1],h[l])*t1 = h[l]*t1,t1 < t,所以当前ans小于上一个的ans
2.h[r1] < h[l] 那么当前ans = min(h[r1],h[l])*t1 = h[r1]*t1,很明显当前ans小于等于上一个的ans。
所以此时我们发现,移动高度较高的那边的指针是毫无意义的,并不会求得比当前ans更大的ans,也就是说以当前高度较小的指针那边为起点是没有意义的,需要将其进行移动,因此我们有了本题的双指针思路。

代码如下

class Solution {
    public int maxArea(int[] height) {

        int l = 0,r = height.length - 1;
        int ans = 0;
        int t = 0;
        while(l < r){
            
            //计算长
            t = r - l;

            //计算面积,两边较短的一边乘以t
            ans = Math.max(Math.min(height[l],height[r])*t,ans);

            //移动较短的一段指针,原有见:需要证明
            if(height[l] >= height[r]){
                r--;
            }else{
                l++;
            }
        }

        return ans;

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值