美文网首页LeetCode每日一题
LeetCode每日一题:盛水最多的容器

LeetCode每日一题:盛水最多的容器

作者: Patarw | 来源:发表于2020-07-17 15:22 被阅读0次
  • 示例:
    输入:[1,8,6,2,5,4,8,3,7]
    输出:49
1.首先先介绍暴力解法,也就是最容易想出来的方法
  • 大体思路就是遍历,把所有结果都遍历一遍然后相比较,最后返回最大的那个
    public int maxArea(int[] height) {             
        int res = 0;        
        for(int i = 0;i < height.length;i++){   
          for(int j = i;j < height.length;j++){ 
            if(res < Math.min(height[i], height[j]) * (j - i)) {
                res = Math.min(height[i], height[j]) * (j - i);             
            }               
         }
        }
        return res;
  }

虽然简单但是时间复杂度还不是最优

  • 时间复杂度:O(N!)
2.第二种方法就是双指针,这也是目前的官方给出的最优方法
  • 算法流程: 设置双指针 left,right分别位于容器壁两端,根据规则移动指针,并且更新面积最大值 res,直到 left == right 时返回 res。

  • 指针移动规则与证明: 每次选定围成水槽两板高度 height[left],height[jright] 中的短板,向中间收窄 1 格。以下证明:

    • 设每一状态下水槽面积为 S(left, right),(0 <= left < right < height.length),由于水槽的实际高度由两板中的短板决定,则可得面积公式 S(left, right) = min(height[left], height[right]) × (right - left)
    • 在每一个状态下,无论长板或短板收窄 1 格,都会导致水槽底边宽度 −1
      • 若向内移动短板,水槽的短板 min(height[left], height[right])可能变大,因此水槽面积 S(left, right) 可能增大。
      • 若向内移动长板,水槽的短板 min(height[left], height[right])不变或变小,下个水槽的面积一定小于当前水槽面积。
  • 代码实现

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

    }

  • 时间复杂度:O(N),双指针总计最多遍历整个数组一次
  • 空间复杂度:O(N),只需要额外的常数级别的空间

相关文章

网友评论

    本文标题:LeetCode每日一题:盛水最多的容器

    本文链接:https://www.haomeiwen.com/subject/fcpghktx.html