[LeetCode-双指针-中等] 盛最多水的容器

这道题主要是考双指针

题目大概是这样的,就是说给定一个长度为n的整数数组height, 代表Y轴上的n条垂线,其中,第i条线的两个端点是(i,0) 和 (i,height[i])  => 要在这n条垂线中找出其中的2条,使得它们和x轴共同构成的容器可以容纳最多的水

返回容器可以储存的最大水量

 

 

这个题目,我自己总觉得题目有点说错了,可能我还没理解

比如数组 height [1,8,6,2,5,4,8,3,7] , 也就是上面图所示的

第一个竖轴  =》 按照题目的说法, 第i条线的两个端点是(i,0) 和 (i,height[i]) =》 所以第1条线的两个端点是(1,0) 和 (1, height[1])  但是显然应该是height[0]才对,因为数组下标是从0开始的 =》 所以我个人觉得题目应该是 第i条线的两个端点是 (i,0) 和 (i,height[i-1]) 才对

好了, 我们来看上面的例子

height 数组总共有9个元素,所以应该是9条线,这9条线的坐标分别为:

第1条: X轴坐标 (1,0)   Y轴坐标 (1,height[1-1]) = (1,height[0]) = (1,1)

第2条  X轴坐标 (2,0) Y轴坐标 (2,8)

第3条  X轴坐标 (3,0) Y轴坐标 (3,6)

第4条  X轴坐标 (4,0) Y轴坐标 (4,2)

第5条  X轴坐标 (5,0) Y轴坐标 (5,5)

第6条  X轴坐标 (6,0) Y轴坐标 (6,4)

第7条  X轴坐标 (7,0) Y轴坐标 (7,8) 

第8条  X轴坐标 (8,0) Y轴坐标 (8,3)

第9条  X轴坐标 (9,0) Y轴坐标 (9,7)

 这道题,显然我们看第一根竖轴和最后一根竖轴  X(1,0)  Y(1,1)  和 X(9,0) Y(9,7) 围成了一个长方形 , 显然,这个长方形的长度是9-1=8, 而高度是2个Y轴=》1和7之间最小的那个,也就是1, 所以面积是 8 *1 = 8. 为了找到最大的面积,我们就要移动竖轴的位置,要么是往右移(从第1根竖轴变成第2根竖轴),要么往左移(从第9条竖轴变成第8条竖轴)=》所以,这里,我们就容易想到双指针的方法,左边是左指针,右边是右指针 =》 那么每次到底应该移动哪个指针呢

这里就有一个点,就是我们要移动竖轴值小的那个指针,也就是说每次移动时,不是固定的每次都移动左指针,或者每次都移动右指针,而是每次都要移动对应的竖值较小的那个指针。=》 为什么要这样移动呢,因为我们目标是求面积最大值,我们假设我们不移动对应Y轴值较小的指针,而是移动Y轴值较大的指针,看看会出现啥情况:

 目前,左指针指向坐标  X(1,0) Y(1,1)   右指针指向坐标X(9,0) Y(9,7)  显然,此时右指针指向的Y轴值较大,如果我们移动右指针,会出现以下情况:

1.  右指针新指向的Y轴值 > 左指针的Y轴值  =》 容器的高取决于左指针(和移动前一样),但是横轴长度变短了,所以面积变小

2.  右指针新指向的Y轴值 = 左指针的Y轴值 =》 容器的高没有变,还是左指针的Y轴值,但是横轴长度变短了,所以面积变小

3.  右指针新指向的Y轴值 < 左指针的Y轴值 =》 容器的高变小了,变成右指针的Y轴值,横轴长度也变短了,所以面积变小

从上面的分析看出,如果我们移动Y轴值较大的指针,一定会导致面积变小,而题目要求是找到最大的容器面积,所以我们应该移动对应Y轴较小的指针,才有可能找到最大的容器面积

 好了,现在我们开始来写代码,C++代码逻辑如下: 

1. 采用while循环,左指针位置left=0,是最左边的, 右指针位置right=height.size() -1 是最右边的  => while(left < right) 就要移动指针,直到两指针相遇,就是完成了所有可能出现的最大面积的查找

2.  最大容器面积等于 (right-left) 长度  *  (height[left] 和 height[right]中较小的那个)   = max  (初始的最大容器面积)

         也就是   (right - left)  * min(height[left],height[right])  = maxArea

      初始化返回值 reArea = 0;  reArea = max(reArea,maxArea);

3. 移动height[left] 和 height[right]中较小的那个指针

                 height[left] <= height[right]       ++left

                 height[left] > height[right]         ++right

 代码如下

复制代码
public:

int maxArea(vector<int>& height)
{
   int left = 0, right = height.size() - 1;
   int reArea = 0;
   
   while(left < right)
   {
        int maxArea = min(height[left],height[right]) * (right - left);
        reArea = max(reArea,maxArea);

        if(height[left] <= height[right])
            ++left;
        else
            --right;
   }  



  return reArea;
}
复制代码

 

              

posted on   新西兰程序员  阅读(7)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示