Description:
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.
Language: C++
解法一:Time Limit Exceeded
暴力解法,遍历所有i,j可能的组合,然后依次判断是否结果大于当前最大容量volume。对于数据量庞大(如15000)时超时Time Limit Exceeded不能AC。
Time:
O(n2)
O
(
n
2
)
Space:
O(1)
O
(
1
)
class Solution {
public:
int maxArea(vector<int>& height) {
assert(height.size() > 1);
int maxwater = 0, i = 0, j = height.size()-1;
for(int i = 0; i < height.size()-1; i++){
for(int j = i+1; j < height.size(); j++){
int h = height[i] > height[j] ? height[j] : height[i];
if(h * (j - i) > maxwater)
maxwater = h * (j - i);
}
}
return maxwater;
}
};
解法二:AC
基本思想:对撞指针。
思路:这道题是可以用对撞指针去做的,不确定的话就画个图试试。问题要求的是最大的volume,如果不好理解,可以先画个图,看看具体是怎么变动的。i从头开始,j从尾开始,比较height[i]和height[j],较小的那个(短板)决定了我们能装多少水,此时高的板再高也没有用,水量已经被短板决定,而我们是为了找最大的volume,所以继续找一个板大于当前短板。
如height[i] < height[j], 此时挪动j只可能找到比当前水量更少的水量(如果j板更大或相等,最小高度都是height[i]不变,由于距离更近了,此时只可能更小; 如果找到一个比height[i]更小的板,那么只可能更小了),因此我们要挪动的是i,使得另一个height[i]大于当前height[i],来得到更多的水量。
另:liuyubobobo老师的解答:
“我们可以形象的理解一下初始的情况是底边最长的情况在这样的情况下如果存在容积更大的容器底边肯定会缩小。此时唯一的方法就是增加高度。我们每次都尝试舍弃两边最短的那个高度来看新的高度能不能构建出容积更大的容器出来”
| |
| | | | |
| | | | | | | |
----------------------
start i j
i j
i j
i j
i j
i j
i j
end ij
Time:
O(n)
O
(
n
)
Space:
O(1)
O
(
1
)
class Solution {
public:
int maxArea(vector<int>& height) {
assert(height.size() > 1);
int maxwater = 0, i = 0, j = height.size()-1;
while(i < j){
int h = height[i] > height[j] ? height[j] : height[i];
if(h * (j - i) > maxwater)
maxwater = h * (j - i);
if(height[i] < height[j])
i++;
else
j--;
}
return maxwater;
}
};