文章目录
- 一、题目
- 二、我的解法:双重for循环,超出时间限制
- 三、最优解法:双指针从两侧开始遍历
【LeetCode】11,盛最多水的容器。 难度等级:中等。
一、题目
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
二、我的解法:双重for循环,超出时间限制
最容易想到的就是暴力循环,双重for循环遍历所有情况,取最大。时间复杂度为 O(n^2), 超出时间限制。code:
class Solution {
public:
int max(int a,int b){
return a>b?a:b;
}
int min(int a,int b){
return a<b?a:b;
}
int maxArea(vector<int>& height) {
int length=height.size();
int maxWater=0;
for(int i=0;i!=length-1;i++)
for(int j=i+1;j!=length;j++){
maxWater=max(maxWater,min(height[i],height[j])*(j-i));
}
return maxWater;
}
};
三、最优解法:双指针从两侧开始遍历
矩形的面积与两个因素有关:
(1)矩形的长度:两条直线的距离
(2)矩形的宽度:两条直线其中较短一条的长度
因此,要矩形面积最大化,两条垂直线的距离越远越好,两条垂直线的最短长度也要越长越好。
我们设置两个指针 left 和 right,分别指向数组的最左端和最右端。此时,两条直线的距离是最远的,若要下一个矩形面积比当前面积来得大,必须要把 height[left] 和 height[right] 中较短的直线往中间移动,检查是否可以找到更长的直线。
code:
class Solution {
public:
int max(int a,int b){
return a>b?a:b;
}
int min(int a,int b){
return a<b?a:b;
}
int maxArea(vector<int>& height) {
const int length=height.size();
int left=0;
int right=length-1;
int maxWater=0;
while(left<right){
maxWater=max(maxWater,min(height[left],height[right])*(right-left));
if(height[left]<height[right])
left++;
else
right--;
}
return maxWater;
}
};