原题链接:https://leetcode-cn.com/problems/container-with-most-water/description/
看着上面图片就可以知道,容纳水量最多其实就是(j-i)*min(aj,ai),其中j和i为这两条垂直线的横坐标,aj和ai为其纵坐标。
思路:设立两个指针,一个从头一个从尾,相向而行遍历数组,每次舍弃较短边
(1)计算面积最大值的初值,该初值以数组中的第一个元素和最后一个元素构成两边。
(2)设置首尾两个指针,首指针i指向数组中的第一个元素,尾指针j指向数组中的最后一个元素。
(3)当首指针i小于尾指针j时,一直循环计算其面积。若计算所得的当前面积大于(1)步骤中所计算得的面积最大值,则更新最大值。每一次循环都舍弃索引i和索引j中较短的那一条边。
由于整个过程只遍历了一次数组,因此时间复杂度为O(n),其中n为数组height的长度。而使用空间就是几个变量,故空间复杂度是O(1)。
python:
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
"""
逼近法
每次左右两端都舍去短的那一端
若选择短的那一端【S=小于等于此端的高*小于等于当前的最大区间长度】
至多的面积也是选择最左最右的一个矩形,因此不必再考虑短的一端,直接舍去逼近
"""
# 记录当前最大容量的面积
max_area = 0
# 记录最左边的下标
left = 0
# 记录右边的下标
right = len(height) - 1
# 当右边下标大于左边下标的时候循环
while right > left:
# 当前循环中最大的容量面积,使用max方法比较上次的max_area和此次的容量面积,取最大值
# min(height[left], height[right]) * (right - left) 取左边和右边的高当中的最小值, 下标right-left为宽,两者相乘为最大面积
max_area = max(max_area, min(height[left], height[right]) * (right - left))
# 判断哪条高小,小的那边下标进行操作
if height[right] > height[left]:
left += 1
else:
right -= 1
return max_area
java:
public class Solution {
public int maxArea(int[] height) {
int n = height.length;
int i = 0;
int j = n - 1;
int area = (n - 1) * Math.min(height[i], height[j]);
while(i < j) {
area = Math.max(area, (j - i) * Math.min(height[i], height[j]));
if(height[i] < height[j]) {
i++;
}else {
j--;
}
}
return area;
}
}