描述
给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
例子
思路
- 动态规划不合适,因为子问题的解无法为问题的解提供帮助
- 关键:i,j为容器的壁,则宽为:j-i,高为 (height[i], height[j])
- 方法1 : 暴力法,两个for循环
- 方法2:两个指针,一个从头开始,一个从尾开始,此时容器的宽最大,然后逐渐减少宽,如果还想盛水更多,则该容器的壁必须要更高,值小的指针向内移动【因为要求最大值,向内移动即宽变小,值大的向内移动的话,移动后的两个指针指向的值的最小<=之前的小值,面积肯定更小】
答案 - java
class Solution {
public int maxArea(int[] arr) {
int res = 0;
int i=0,j=arr.length-1;
while(i<j) {
int high = Math.min(arr[i],arr[j]);
res =Math.max(res, high*(j-i));
if(high==arr[i]) i++;
else j--;
}
return res;
}
}
- python
*方法1*
def maxArea(self, arr: List[int]) -> int:
area = 0
for i in range(len(arr)):
for j in range(i+1,len(arr)):
height = arr[i] if arr[i]<arr[j] else arr[j]
width = j-i
if height*width>area:
area = height*width
return area
*方法2*
def maxArea(self, height: List[int]) -> int:
i,j=0,len(height)-1
area = 0
while i<j:
h = min(height[i], height[j])
area = max(area, h*(j-i))
if height[i]<height[j]: i+=1
else: j-=1
return area
- c++
*方法1*
int maxArea(vector<int>& height) {
int area=0;
for (int i=0; i<height.size(); i++)
for (int j=i+1; j<height.size(); j++)
{
int h = min(height[i],height[j]);//最短的板
area = max(h*(j-i),area);
}
return area;
}
*方法2*
int maxArea(vector<int>& height) {
int area=0;
int i=0,j=height.size()-1;
while (i<j)
{
int h = min(height[i], height[j]);
area = max(area, h*(j-i));
if (height[i]<height[j]) i++;
else j--;
}
return area;
}