【LeetCode每日一题】盛最多水的容器

微信公众号:程序员Alex
关注可了解更多的编程知识。问题或建议,请公众号留言;
如果你觉得文章对你有帮助,欢迎关注分享

盛最多水的容器

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

说明

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

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

示例:

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

解题思路

​ 通过分析题目,结合图表可以发现,此题其实就是求数组元素组成的长方形的最大面积。数组中的元素代表长方形的长,两个元素之间的距离(坐标差)就是长方形的宽。取数组中的第m和第n个数(满足m < n),结合木桶效应,长方形的长取决于相对短的。得出以下公式:

长 = M i n ( h e i g h t [ m ] , h e i g h t [ n ] ) 长 = Min(height[m] , height[n]) =Min(height[m],height[n])
宽 = n − m 宽 = n - m =nm
容 量 = M i n ( h e i g h t [ m ] , h e i g h t [ n ] ) ∗ ( n − m ) 容量 = Min(height[m] , height[n])* (n-m) =Min(height[m],height[n])(nm)
求最大容量则需要计算出所有可能的容量,取其中最大值。

方法1 采用双指针法

  1. 确定左右指针

    左指针 left :数组的第0个元素

    右指针 right :数组的最后一个元素

  2. 计算容量(长方形面积)

    m a x A r e a = M i n ( h e i g h t [ l e f t ] , h e i g h t [ r i g h t ] ) ∗ ( r i g h t − l e f t ) maxArea = Min(height[left] , height[right])* (right-left) maxArea=Min(height[left],height[right])(rightleft)

  3. 挪动指针

    条件:将指针指向元素较小的指针向另一个指针靠近一个单位

  4. 计算指针移动后容量,并与之前的最大容量做比较,更新最大容量值。

  5. 重复步骤3和4,直至指针相遇。

核心代码实现

完整代码:https://github.com/tinet-shenjg/leetCode4J

/**
 * 计算最大容量
 *
 * @param height n 个非负整数集合
 *
 * @return 最大容量
 */
public static int maxArea(int[] height) {
    // 定义最大容量
    int maxArea = 0;

    // 采用双指针来计算最大容量
    int left = 0;
    int right = height.length - 1;

    // 指针第一次相遇为终结点
    while (left < right) {
        // 计算当前的最大容量
        maxArea = Math.max(maxArea, Math.min(height[left], height[right]) * (right - left));

        // 移动指针,相对短的木板向另一侧一定
        if (height[left] > height[right]) {
            right--;
        } else {
            left++;
        }
    }
    return maxArea;
}

测试用例

public static void main(String[] args) {
        int[] height = {1, 8, 6, 2, 5, 4, 8, 3, 7};
        System.out.println(maxArea(height));
        System.out.println(maxArea2(height));
 }
复杂度分析

时间复杂度O(n)

空间复杂度O(1)

方法2 暴力穷举

​ 不推荐此方法,两层循环遍历数组即可。

代码实现
 public static int maxArea2(int[] height) {
        int maxarea = 0;
        for (int m = 0; m < height.length; m++){
        		for (int n = m + 1; n < height.length; n++){
            		maxarea = Math.max(maxarea, Math.min(height[m], height[n]) * (n - m));
            }
        }      
        return maxarea;
    }

复杂度分析

时间复杂度O( n 2 n^2 n2)

空间复杂度O(1)
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值