leetcode011:Container With Most Water

问题描述

Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (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.

问题分析

木桶装水问题,乍一想要符合木桶效应:一只水桶能装多少水取决于它最短的那块木板。这里要从数组列表中找到两块“木板”能围住的最大面积(以较低的木板为高)。

  • 一开始想到的解决方案也是最省事儿的办法就是针对每条“木板”i找到比它高的木板中离它最远的那条j,i和j围住的区域则是i木板所能围住的最大面积,每条木板都需要扫描n次,所以其算法复杂度为n^2.然后运行就提示超时了。见代码:
class Solution {
public:
    int maxArea(vector<int> &height) {
        vector<int> p(height.size(), 0);//记录每条木板对应的"最远木板"
        for (int i = 0; i < height.size(); i++){
            for (int j = 0; j < height.size(); j++){
                if (j != i && height[i] <= height[j]){
                    if (p[i] < abs(j - i)){
                        p[i] = abs(j - i);
                    }
                }
            }
        }
        int ans = 0;
        for (int i = 0; i < height.size(); i++){
            int area = height[i] * p[i];
            if (area > ans) ans = area;
        }
        return ans;
    }
};
  • 随后在草纸上模拟,当我画出如下图的时候,算法也自然就出来了,复杂度为O(n).
    举例:height数组为{2,3,8,5,6,1},这里以坐标0起始。
    这里写图片描述
    可以看出,我们只要从两端向中间扫描,每次留长弃短即可,特殊情况两板相同则同时舍弃。
    附accept代码:
class Solution {
public:
    int maxArea(vector<int> &height) {
        int i=0,j=height.size()-1;
        int ans = 0;
        int area;
        while (i < j){
            if (height[i] < height[j]){
                area = (j - i) * height[i];
                i++;
            }
            else if (height[i] > height[j]){
                area = (j - i) * height[j];
                j--;
            }
            else {
                area = (j - i) * height[j];
                i++; j--;
            }
            if (area > ans) ans = area;
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值