面试题-盛最多水的容器

题目描述
给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
面试题-盛最多水的容器_第1张图片
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例:
输入: [1,8,6,2,5,4,8,3,7]
输出: 49

题解
之前写过一版 [这里],但图配的不好,现重新画一下。

求容器能够容纳水的最大值,其实就是求矩形的最大面积。
我们定义两个指针来代表两个柱子,之后两个指针指向的较小者向中间移动,每次移动之前计算一下当前的面积,并保存下来,等到两个指针相遇时(即两个指针都指向同一个柱子时),遍历结束。
怎么计算矩形面积呢?
比如这个数组:
[1,8,6,2,5,4,8,3,7]
下标1的值是8,下标8的值是7。通过值和下标这两个维度就可以计算矩形了。
面试题-盛最多水的容器_第2张图片
将右边下标减去左边下标,得到矩形的宽度
再计算max(arr[1],arr[8])得到矩形的高度
有了长度和高度就可以得出面积了。

完整的幻灯片演示如下:
面试题-盛最多水的容器_第3张图片
面试题-盛最多水的容器_第4张图片
面试题-盛最多水的容器_第5张图片
面试题-盛最多水的容器_第6张图片
面试题-盛最多水的容器_第7张图片
面试题-盛最多水的容器_第8张图片
面试题-盛最多水的容器_第9张图片
面试题-盛最多水的容器_第10张图片
面试题-盛最多水的容器_第11张图片
每次比较左右指针,选择较小的那个向左/向右 移动
比如 左边的1比右边的7小,那么选择移动左边的1
如果每次都移动大的,那结果就不对了 如果每次移动大的,那就向上图那样,右指针不断往左移动,但是左指针一直没变化过,计算出的计算面积就是8。
面试题-盛最多水的容器_第12张图片

时间复杂度:O(n)
空间复杂度:O(1)

java代码:

class Solution {
    public int maxArea(int[] height) {
        if(height==null) {
            return 0;
        }
        //定义两个指针,分为位于最左边和最右边
        int i = 0;
        int j = height.length-1;
        int res = 0;
        //两个指针不断像中间移动,每迭代一次都会计算矩形的最大面积
        while(i

Python代码

class Solution(object):
    def maxArea(self, height):
        if not height:
            return 0
        # 定义两个指针,分为位于最左边和最右边 
        i = 0
        j = len(height)-1
        res = 0
        # 两个指针不断像中间移动,每迭代一次都会计算矩形的最大面积
        while i
func maxArea(a []int) int {
    n := len(a)
 
    if n < 2 {
        return 0
    }
 
    if n == 2 {
        return min(a[1], a[0])
    }
 
    max := min(a[n - 1], a[0]) * (n - 1)
 
    i := 0
    j := n - 1
 
    for i < j  {
        if a[i] < a[j] {
            i++
        }else {
            j--
        }
 
        area := min(a[i], a[j]) * (j - i)
        if area > max {
            max = area
        }
    }
 
    return max
}
 
func min(x, y int) int {
    if x < y {
        return x
    }
 
    return y
}

你可能感兴趣的:(java)