题目链接:https://leetcode-cn.com/problems/container-with-most-water
题目描述
给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明: 你不能倾斜容器,且 n 的值至少为 2。
示例1:
输入: [1,8,6,2,5,4,8,3,7]
输出: 49
我的思路
- 继上一题还没彻底搞明白,又开始搞其他的了。
- 一上来就整一个柱状图,挺唬人,其实仔细看题没那么可怕。
- 首先就是不想动脑子,写了个暴力的:
class Solution {
public:
int maxArea(vector<int>& height) {
int maxAr = 0;
for(int i = 0; i < height.size(); i++){
for(int j = i+1; j < height.size(); j++){
if(height[j] <= height[i]){
maxAr = max(maxAr, height[j] * (j-i));
}
if(height[j] > height[i]){
maxAr = max(maxAr, height[i] * (j-i));
}
}
}
return maxAr;
}
};
- BOOM!又炸了。(为什么说又呢…)在 LeetCode 那变态的测试用例前,这种不走脑子的做法果然不行。
- 这个算法显然很慢,有 O(n^2) 的时间复杂度。仔细考虑之下,发现这道题和许多数组题解法一样,可以使用双指针。也就是一个指针指向开始,一个指向末尾,然后哪个指针指向的线段最短,哪个就往中心移动。
- 然后算法的时间复杂度就来到了 O(n),空间复杂度O(1)。
- 所以学好算法你看多有用!(专治思维懒惰)
代码如下:
class Solution {
public:
int maxArea(vector<int>& height) {
int maxAr = 0, l = 0, r = height.size()-1;
while(l < r){
if(height[l] <= height[r]){
maxAr = max(maxAr, height[l] * (r-l));
l++;
}
if(height[l] > height[r]){
maxAr = max(maxAr, height[r] * (r-l));
r--;
}
}
return maxAr;
}
};