题目:
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 iis 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
描述:
给出一列数值,表示在每个坐标点处的线的高度,问给出的样例中,若把任意两条线作为侧壁(厚度不计),问最多能盛多少水?
分析:
真的很想说:没有数据范围的题目就是耍流氓!!!!
看到题感觉跟很久以前见过的某道题类似,想来想去没找到很好的思路,算了,还是先暴力试一试...
额,竟然AC了??? (见下面代码一)
无奈...
虽然做出来了,但是还是觉得这样就放过他不太合适,再看看有没有线性时间的解法...
感觉可以用贪心思想去做,比如木桶盛水的多少取决于最短的边,那么要是每次都把边增加,就能迭代了,然后再去记录该过程中出现过的最大容积,但是,迭代的起点在哪呢?
emmmmm...
参阅了一篇博客,获得了线性解的思路:(见代码二)
以底边最长为迭代的起点,哪一侧的木板短,哪一侧的侧边便往里收缩(因为这边已经是瓶颈了,换一个侧壁后容积增大的可能性较大)
代码一:(时间复杂度 O(n^2))
class Solution {
public:
int min(int a, int b) {
return a > b ? b: a;
}
int maxArea(vector<int>& height) {
int result = 0, current = 0;
for (int i = 0; i < height.size(); ++i) {
for (int j = i + 1; j < height.size(); ++j) {
current = min(height[i], height[j]) * (j - i);
if (current > result) {
result = current;
}
}
}
return result;
}
};
代码二:(时间复杂度O(n))
class Solution {
public:
int min(int a, int b) {
return a > b ? b: a;
}
int maxArea(vector<int>& height) {
int left = 0, right = height.size() - 1;
int result = 0, current = 0;
do {
current = min(height[left], height[right]) * (right - left);
if (current > result) {
result = current;
}
if (height[left] < height[right]) {
++ left;
} else {
-- right;
}
} while (left < right);
return result;
}
};