Leetcode11 Container With Most Water

Leetcode11: Container With Most Water

题目论述

  • 链接:Leetcode11: Container With Most Water

  • 概述:

    Given n non-negative integers a 1 , a 2 , . . . , a n a_1, a_2, ..., a_n a1,a2,...,an , where each represents a point at coordinate ( i , a i ) (i, a_i) (i,ai). n vertical lines are drawn such that the two endpoints of line i is at ( i , a i ) (i, a_i) (i,ai) and ( i , 0 ) (i, 0) (i,0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

    Note: You may not slant the container and n is at least 2.

    img

    The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.

    Example:

    Input: [1,8,6,2,5,4,8,3,7]
    Output: 49
    

思考分析

  1. 问题转数学语言表达:

    ​ 这道题叙述上是求n个不等高的柱子等距1排放,如何选出两个柱子,使得柱子之间形成的长方形的“盛水容器”面积更大。实际上该长方形的高度取决于两根柱子之间较矮的那根,其宽度取决于两根柱子之间的距离。

    ​ 那么转换成数学语言即是:

    ​ 在数组A中,如何选出两个数 A [ i ] A[i] A[i] A [ j ] A[j] A[j] ( i &lt; j ) (i &lt; j) (i<j),使得值 m i n ( A [ i ] , A [ j ] ) ⋅ ( j − i ) min(A[i], A[j])·(j-i) min(A[i],A[j])(ji)的值最大。

  2. Solution1:

    ​ 第一个很容易想到的解法,当然是两个循环体遍历任意两个数的组合,算出每对组合数的对应面积,取最大的面积即是答案。这样的复杂度为 O ( n 2 ) O(n^2) O(n2)

  3. Solution2:

    ​ 我们考虑一下是否存在 O ( n ) O(n) O(n)的解法,我们首先先保证宽度最大,也即先选出最左边的柱子和最右边的柱子。那么暂定最大面积为这两根柱子之间的容器面积。

    ​ 那么下面要考虑高度的问题,我们从较矮的那根柱子开始往另一边移动1步,那么移动后有一个新的容器面积,我们只需要比较暂定最大面积和这个新的容器面积,将较大的那个重新赋值给暂定最大面积即可。重复考虑新的两根柱子的移动问题,直到两根柱子移动n-1次并到一起,这时候得到的最大面积就是答案。

    ​ 事实上这样的逼近是合理的。因为如果新的容器面积比暂定最大面积大,那么最大面积就与之前暂定最大面积移动的那根柱子无关了。而如果新的容器面积比之前的暂定最大面积小,那么最后结果的最大面积一定不是由移动后的这根柱子形成的,所以可以继续往后逼近。


code(c++)

  • Solution 1 (1424ms)
class Solution {
public:
    int maxArea(vector<int>& height) {
       	int area = min(height[1], height[0]);
        for(int i = 0; i < (int)height.size(); i++) {
            for (int j = i+1; j < (int)height.size(); j++) {
                area =  max(area, min(height[i], height[j])*(j-i));
            }
        }
        return area; 
    }
};
  • Solution 2 (12ms)
class Solution {
public:
    int maxArea(vector<int>& height) {
        int size = height.size();
        int max_area = min(height[0], height[size-1]) * (size-1);
        int head = 0, tail = size - 1;
        while(head < tail) {
            if(height[head] < height[tail]) {
                max_area = max(max_area, height[head] * (tail - head));
                head++;
            }
            else {
                max_area = max(max_area, height[tail] * (tail - head));
                tail--;
            }
        }
        return max_area;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值