题目描述
解题思路
1、暴力解
本题可以看作是一个组合的问题,就是组合数组中的两个数计算一个值,该值为:(大下标-小下标)*小数值
,那我们就直接通过两个for循环,把所有组合找出来,然后求值,取最大的值即可。
直接上代码:
Java代码:
public class Solution {
public int maxArea(int[] height) {
int area = 0;
for (int i = 0; i < height.length - 1; i++) {
int tempArea = 0;
for (int j = i + 1; j < height.length; j++) {
tempArea = Math.max(tempArea, (j - i) * Math.min(height[i], height[j]));
}
area = Math.max(area, tempArea);
}
return area;
}
}
算法的时间复杂度为O(n^2),空间复杂度为O(1),显然不是的解题办法
2、双指针解法
我们使用两个指针,一个指向头一个指向尾,同时相向而行,每次比较两端的值,舍弃较小的值
- 设置两指针,i指向数组中的第一个元素,j指向数组中的最后一个元素
- 计算数组中的第一个元素和最后一个元素构成的容器的面积,作为最大值的初始值
- 当指针i小于指针j时,执行循环计算面积,若计算的面积大于之前计算的最大值,则更新最大值
补充:为何是舍弃较小的值
- 假设两指针分别指向数组
arr
的第i
和第j
个元素,且arr[i] < arr[j]
- 如果我们舍弃的是较大的值,那么
j
往左移动,与i
构成的矩形的宽一直在减小- 若
arr[j-1] > arr[i]
,由于较小值arr[i]
的限制,其构成的矩形的高还是arr[i]
,但是宽减小了,因此面积减小- 若
arr[j-1] < arr[i]
,由于较小值a[j-1]
的限制,其构成的矩形的高为arr[j-1]
,宽减小,高比arr[i]
小,那么面积比原先的小- 综上,如果舍弃较大的值,那么得到面积不会比现在的大,因此需要舍弃较小的值
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;
}
}
Python3代码:
class Solution:
def maxArea(self, height: List[int]) -> int:
n = len(height)
i = 0
j = n - 1
area = (n - 1) * min(height[i], height[j])
while i < j:
area = max(area, (j - i) * min(height[i], height[j]))
if height[i] < height[j]:
i += 1
else:
j -= 1
return area
C++代码:
class Solution {
public:
int maxArea(vector<int>& height) {
int n = height.size();
int i = 0;
int j = n - 1;
int area = (n - 1) * min(height[i], height[j]);
while(i < j){
area = max(area, (j - i) * min(height[i], height[j]));
if(height[i] < height[j]) {
i++;
}else {
j--;
}
}
return area;
}
};