题目
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
eg: [1,8,6,2,5,4,8,3,7] ->49
问题分析
双指针法详解
收缩短板,因为只有短板才会造成容积增大。
改变长板,对于新的min(height[r],height[l])一定是小于之前的min(height[r],height[l]),而r-l是一定减小的,所以无意义。
C++题解
暴力跑
class Solution {
public:
int maxArea(vector<int>& height) {
int maxans = -1;
for(int i = 0; i < height.size() - 1; i++){
for(int j = i + 1; j < height.size(); j++){
maxans = max(maxans, (j - i)*min(height[i], height[j]));
}
}
return maxans;
}
};
结果超时
所以暴力方法的时间O(n^2)超过了限制时间。
考虑到动态规划条件不满足,在这采用双指针方法(O(n))。
双指针法
int maxArea(vector<int>& height) {
int ans = 0;
int i = 0;
int j = height.size() - 1;
while (i < j) {
ans = max(ans,(j - i) * min(height[i], height[j]));
if (height[i] < height[j]) {
i++;
} else {
j--;
}
}
return ans;
}
AC结果
Python题解
class Solution:
def maxArea(self, height: List[int]) -> int:
left = 0
right = len(height) - 1
ans = -1
while(left < right):
ans = max(min(height[left], height[right])*(right-left), ans)
if(height[left] < height[right]):
left += 1
else:
right -= 1
return ans