LeetCode-Container With Most Water

https://leetcode-cn.com/problems/container-with-most-water/

这道题最开始看觉得难度应该不是 Medium,但发现运行时间很长,复杂度是 O(n^2),所以应该有更精妙的解法。

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public int maxArea(int[] height) {
int maxVolume=0;
for(int i=0;i<height.length;i++){
for(int j=i+1;j<height.length;j++){
int v=(j-i)*Math.min(height[i],height[j]);
maxVolume=Math.max(v,maxVolume);
}
}
return maxVolume;
}
}

看了 Solution 以后才明白,从两端开始,慢慢往中间收缩,这样复杂度可以降为 O(n)。

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public int maxArea(int[] height) {
int maxVolume=0;
int left=0,right=height.length-1;
while(right>left){
maxVolume=Math.max(maxVolume,(right-left)*Math.min(height[left],height[right]));
if(height[left]>height[right]) right--;
else left++;
}
return maxVolume;
}
}

看了他人的解法以后,发现通过淘汰一些情况,还能再快一些。

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public int maxArea(int[] height) {
int maxVolume=0;
int left=0,right=height.length-1;
while(right>left){
int mLeft=height[left],mRight=height[right];
maxVolume=Math.max(maxVolume,(right-left)*Math.min(height[left],height[right]));
if(mLeft>mRight) while(left<right && height[right]<=mRight) right--;
else while(left<right && height[left]<=mLeft) left++;
}
return maxVolume;
}
}

C++版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
int maxArea(vector<int>& height) {
int i=0,j=height.size()-1;
int maxWater=0;
while(i<j){
int tLeft=height[i],tRight=height[j];
maxWater=max(maxWater,(j-i)*min(tLeft,tRight));
if(tLeft<tRight) while(i<j && height[i]<=tLeft) i++;
else while(i<j && height[j]<=tRight) j--;
}
return maxWater;
}
};