【LeetCode】11,盛最多水的容器。 难度等级:中等。双指针解法值得深入学习。


【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;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_43799400/article/details/130956526