leetcode 11.乘最多水的容器(双指针法)

leetcode 11.乘最多水的容器

双指针法
题目:给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
leetcode 11.乘最多水的容器(双指针法)_第1张图片
例:输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

下面是我看到这个题目整个思考过程
1,刚看到这个题时,我感觉还挺简单的,应该两个for循环就可以搞定,leetcode 11.乘最多水的容器(双指针法)_第2张图片
这是当时的想法,画了一个流程图。
然后写完后点执行代码,结果一下就成功通过了实例,还是挺开心的,还心想难道是我变强了???这就是中等难度的题???结果当我提交代码时,他竟然提示我代码超时!!然后我又提交了两次,都是超时,满脸的不解,然后看了看他给的测试用例,我被吓到了1秒,这么多数,怪不得超时,我这两for不得执行个几千万次。
后来又想新的办法,都不太理想,只好看了看官方法,瞬间豁然开朗,感觉好机智,第一次接触到双指针法

以下面为例(官方给的解释):
[1, 8, 6, 2, 5, 4, 8, 3, 7]
在初始时,左右指针分别指向数组的左右两端,它们可以容纳的水量为 \min(1, 7) * 8 = 8min(1,7)∗8=8。

此时我们需要移动一个指针。移动哪一个呢?直觉告诉我们,应该移动对应数字较小的那个指针(即此时的左指针)。这是因为,由于容纳的水量是由两个指针指向的数字中较小值 * 指针之间的距离决定的。如果我们移动数字较大的那个指针,那么前者「两个指针指向的数字中较小值」不会增加,后者「指针之间的距离」会减小,那么这个乘积会减小。因此,我们移动数字较大的那个指针是不合理的。因此,我们移动 数字较小的那个指针。

本来在这里还想写一下自己的理解,但发现官方给的解释太好了,所以…还是解释一下吧O(∩_∩)O哈哈~

这是底乘高,让选择最优底和高的题

首先,我们先来选择最长底,因为最长比最高好选择到,最长底就是第一个和最后一个之间的距离,然后算面积,移动底,我们当然要移动数字较小的,因为移动数字较小的一格后的面积减少比移动大的减少的少(感觉这句话可能是我说的重点)
最后,上代码:
int maxArea(int* height, int heightSize){
int max_water=0,cur_water,cur_height;
int start=0,end=heightSize-1;
while(start!=end)
{
cur_height=height[start]-height[end]>0 ? height[end]:height[start];
cur_water=abs(start-end)*cur_height;
if(cur_water>max_water)
{
max_water=cur_water;
}
height[start]-height[end]>0 ? end–:start++;
}
return max_water;
}
这次就到这里了。(∩_∩)

你可能感兴趣的:(leetcode,c语言,leetcode,算法)