题目描述
Given n non-negative integers a1, a2, …, an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container and n is at least 2.
The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.
Example:
Input: [1,8,6,2,5,4,8,3,7]
Output: 49
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
暴力法。简单地考虑每对可能出现的线段组合并找出这些情况之下的最大面积。
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
/// Brute Force
/// Time Complexity: O(n^2)
/// Space Complexity: O(1)
class Solution {
public:
int maxArea(vector<int>& height) {
assert(height.size() >= 2);
int area = 0;
for(int i = 0 ; i < height.size() ; i ++)
for(int j = i + 1; j < height.size() ; j ++)
area = max(area , min(height[i], height[j]) * (j - i));
return area;
}
};
int main() {
vector<int> nums1 = {1, 1};
cout << Solution().maxArea(nums1) << endl;
return 0;
}
思路二
我们在由线段长度构成的数组中使用两个指针,一个放在开始,一个置于末尾。 此外,我们会使用变量 maxareamaxarea 来持续存储到目前为止所获得的最大面积。 在每一步中,我们会找出指针所指向的两条线段形成的区域,更新 maxareamaxarea,并将指向较短线段的指针向较长线段那端移动一步。
或这么理解:
由于面积取决于边长短的那一端假设为m,所以要想得到比当前更大的面积,边长短的那一端必须舍弃,因为如果不舍弃,高最大就是m,而随着指针的移动宽会一直减小,因此面积只会越来越小。
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
/// Two Pointers
/// Time Complexity: O(n)
/// Space Complexity: O(1)
class Solution {
public:
int maxArea(vector<int>& height) {
assert(height.size() >= 2);
int l = 0, r = height.size() - 1;
int area = 0;
while(l < r){
area = max(area , min(height[l], height[r]) * (r - l));
if(height[l] < height[r])
l ++;
else
r --;
}
return area;
}
};
int main() {
vector<int> nums1 = {1, 1};
cout << Solution().maxArea(nums1) << endl;
return 0;
}