Question:
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.
思路:
以(i, ai) 和 (j, aj)到X轴的垂线作为边,X轴作为底,构成一个不可倾倒的容器,求最大容水量,即 | i - j | * min( ai , aj ) 。
第一思路是用2次循环,i从0开始,j从i开始循环,但是在数据量较大时会超时。
那么如何减小时间复杂度呢?
参考网上的其他解法发现,影响容量大小只有两个因素:i-j 和 较小的ai。
如果ai<aj,且i<j 则 ai到aj的容量一定大于ai到ak(k < j)的距离。 因为底边长 j-i > k-i,ai<=min(ai,ak)。
那么也就是说,我们再寻求最大容量的时候,应当尽可能满足底边长时,不改变较高的aj,只需改变较小的ai进行比较,这样最多只需比较n次。
Code:
//代码1
//此代码在数据量较大的情况下超时,其他情况均可通过测试
class Solution {
public:
int maxArea(vector<int>& height) {
int MAX = 0;
int NOW = 0;
for (int i = 0; i < height.size()-1; i++){
for(int j = i+1; j < height.size(); j++){
NOW = (j-i)*(height[i]>height[j]?height[j]:height[i]);
if(MAX<NOW) MAX = NOW;
}
}
return MAX;
}
};
//代码2——改进效率后的代码
class Solution {
public:
int maxArea(vector<int>& height) {
int MAX = 0;
int NOW = 0;
int i = 0;//左值
int j = height.size()-1;//右值
while(i < j){
NOW = (j-i)*(height[i]>height[j]?height[j]:height[i]);
if(MAX<NOW) MAX = NOW;
if(height[i]>height[j]) j--;
else i++;
}
return MAX;
}
};