LeetCode11、盛最多水的容器

1.直接思维法

class Solution {
    
    
    public int maxArea(int[] height) {
    
    
        if(height==null||height.length==0||height.length==1){
    
    
            return 0;
        }
        int max=0;
       for(int j=0;j<height.length;j++)//起点
        {
    
    
            for(int i=1;i<=height.length-1;i++){
    
    //控制底边的长度。
            
                if(j+i<height.length){
    
    
                    int water = Math.min(height[j],height[j+i])*i;
                    if(max<water)
                        max = water;
                }else
                break;
            }

        }

    return max;
}
}

一次就accept,但是效率感人:

在这里插入图片描述
毫无疑问,时间复杂度达到了O(N2)

2.动态规划法

根据清华大佬的说法,动态规划步骤在于:

  • 1、确定状态

确定状态的关键在于:
找出最后一步,然后由最后的一步得出子问题的结构。

这个问题里面,最后的结果就是我们找到了使得盛得的水最多的两个端点:ai,aj,水量res。那么她的上一步是什么?上一步必定是在寻找这两个端点或者其中之一的端点,也就是说:也就是说会出现一个下标移动。于是子问题就有了。我们找当前的ai,aj,需要找到上一次的某两个端点a1,a2,她的盛水量不是最大的。(如何知道不是最大的,我们需要一个记录量,记录当前的最大量,即res)才会出现下标的移动。则有如下的结果:

    • (a[i],a[j])<-(a[i-1],a[j]),if(a[i-1]<a[j])
    • (a[i],a[j])<-(a[i],a[j+1]),if(a[i]>a[j+1])

于是我们可以推出,当计算到a[i][j]时,我们算的当前的最大量为res,接下来,我们无法确定res是否为全局最大,因为我们还没有计算完可能结果。我们还要计算其他的端点组成的值。于是我们需要将下标移动,即怎么移动呢?当height[i]<height[j]则移动的下标应该是i,谁小移动谁,因为:

因为,由于容纳的水量是由
两个指针指向的数字中较小值 * 指针之间的距离
决定的。如果我们移动数字较大的那个指针,那么前者「两个指针指向的数字中较小值」不会增加,后者「指针之间的距离」会减小,那么这个乘积会减小。那么不符合我们要找最大的量的需求。因此,我们移动数字较大的那个指针是不合理的。因此,我们移动 数字较小的那个指针。

于是定义状态,开数组表示。具体还要考虑所开数组的维度和其大小。

  • 2、递推方程
    res = min(res,(j-i)*min(height[i],height[j]));
  • 3、初始条件和边界情况
    初始条件就是我们有这个可能,但是计算不出来,同时又是需要用来递推的。
    这道题没有边界。初始条件:需要两个端点才能盛水。于是height.length<=1,return -1;
  • 4、计算顺序,即用到该值时,其需要已经推出。这里没有要考虑的

在这里插入图片描述
只有做到上面的四步,才开始写代码。

class Solution {
    
    
    public int maxArea(int[] height) {
    
    
      if(height.length<=1)
        return -1;
        int i = 0,j=height.length-1,res = 0;
        while(i<j){
    
    
            int min = Math.min(height[i],height[j]);
            res = Math.max(res,(j-i)*min);
            if(height[i]<height[j]){
    
    
                i++;
            }else j--;
        }
        return res;
    }
}

参考官方题解(双指针法)。这是我第一次真正的感觉自己摸到了动态规划的门。

猜你喜欢

转载自blog.csdn.net/qq_44861675/article/details/108367541