系列文章目录
前言
每天进步一点点!!
一、背景
题目意思我解释一下,这里力扣描述的让人看不太懂!
就是说输入一个数组,把每个数字用条形图的方式画在坐标轴上面,两个数字之间和x轴可以存放水,问:找到两个数字边界,可以存储最多的水,返回水的容量。
来源:力扣
链接:https://leetcode-cn.com/problems/container-with-most-water/
二、我的思路
因为之前做过接雨水等几个比较难的题目,所以刚开始还是按照我自己的思维来,想一步步求出来呢,后面意识到,那样不快,不如用……艾,双指针大法!!
双指针的思路就是,两头开始遍历,找板子,如果哪一边的板子更小,那么让那一边的板子继续前进(后退),看能不能找到一个更大的板子。每次更换了板子,就计算一次水的容积,取最大的。
这样只需要一次遍历即可。
代码如下:
class Solution {
public:
int maxArea(vector<int>& height) {
//由于是找到两条线,办法就是找到左右最大的板子
int max_area=0;
int pleft=0,pright=height.size()-1;//双指针的办法
while( pleft < pright )
{
max_area=max( max_area , (pright-pleft)*min(height[pleft],height[pright]) );
if ( height[pleft] < height[pright] )
{
pleft++;
}
else
{
pright--;
}
}
return max_area;
}
};
三、官方的思路
1.和我一样,双指针
由于思想和我一致,我的代码也没有很复杂,就不贴代码了。
2.优化一下
每次更新了板子都计算一下储水量,其实没必要,那什么时候需要计算呢?新的板子比原来的板子长的时候,就需要计算,这样可以节省时间哟!
这里引入一个变量h,用来记录上一次板子的长度。
class Solution {
public:
/*
优化一下,双指针往内遍历,前提是板子比两侧的高,才能装更多的水
*/
int maxArea(vector<int>& height) {
int l = 0, r = height.size() - 1;
int ans = 0;
int h=0;//临时记录板子的高
while (l < r) {
if ( h >= min(height[l], height[r]) )
{
int x= height[l] <= height[r]? ++l : --r;
continue;
}
h=min(height[l], height[r]);
int area = h * (r - l);
ans = max(ans, area);
int x= height[l] <= height[r]? ++l : --r;
}
return ans;
}
};
可以看到,直接优化了20ms呢,进步了很多,哈哈哈!
总结
双指针的办法一时间很难想到,这是正常的,我也不知道自己做这个题目为什么这么快,自己都觉得不可思议,以前都是调试要好久,也想不出什么办法。
一般来讲,可能会使用动态规划的办法,不过后面学会了这个,可以用双指针呢,不用着急哈!!!
喜欢就来个赞叭,谢谢!!
哦对,圣诞节快乐呀!