Leetcode---11. 盛最多水的容器

🏑11. 盛最多水的容器

2020 5.29 00:13

YongChoir

橘子汽水

✨道阻且长,行则将至


「题目描述」:

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

**说明:**你不能倾斜容器,且 n 的值至少为 2。

img

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

示例:

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

「题解」:

法一:双指针(两侧双指针)

观察可知,如果只有两个柱子ab,那么容积v = minHeight(a, b) * width(b - a) –>v = minH * width. 那么只有通过长、宽两个变量变化来增加体积。那么可以通过增加宽度或者高度又或者同时增加。

  1. 从最左边开始遍历,稳定左边,变化右边–>增大宽度。如此嵌套循环,时间复杂度:O(N^2)

  2. 初始左右柱子为左边界、右边界。那么开始移动,宽度变小,转而只能通过增加高度来找寻最大体积。而最终计算时需要的高度是二柱中矮的。所以我们只需要移动矮的柱子。

    • 证明为什么只移动最矮的柱子:

      假如当前两柱nums[0] nums[i] , if (nums[0] < nums[i]),那么是不用计算nums[i-1]、nums[i-2]...

      证明:

      1. nums[i-1] > nums[i]: minH = nums[0] width变小–>没意义

      2. nums[i-1] < nums[i]:

        1. nums[i-1] = nums[0]: minH = nums[0] width变小–>没意义
        2. nums[i-1] < nums[0]: minH < nums[0] width也变小–>更没意义
        3. nums[i-1] > nums[0]: minH = nums[0] width变小–>没意义
      3. nums[i-1] = nums[i]: minH = nums[0] width变小–>没意义

      所以,可得只用移动较矮的柱子即可。

    「伪码」:

    while (right < nums.length) {
        maxV = max (maxV, (right - left) * min(left, right));
        if (left <= right) {
            left++;
        }else{
            right--;
        }
    }
    

    「Code」:

    class Solution {
        /**
         * 时间复杂度:O(N)
         * 空间复杂度:O(1)
         */
        public int maxArea(int[] height) {
            int left = 0;
            int right = height.length - 1;
            int maxV = (right - left) * Math.min(height[left], height[right]);
            while (left < right) {
                maxV = Math.max(maxV, (right - left) * Math.min(height[left], height[right]));
                if (height[left] <= height[right]) {
                    left++;
                }else{
                    right--;
                }
            }
            return maxV;
        }
    }
    

    Good Evening! 😴 😴 😴

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值