leetcode 11 Container with Most Water

简介: 1.题目描述Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai).

1.题目描述

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 and n is at least 2.

2.中文解释:

给定n个非负整数a1,a2,…,an,其中每个代表一个点坐标(i,ai)。

n个垂直线段例如线段的两个端点在(i,ai)和(i,0)。

找到两个线段,与x轴形成一个容器,使其包含最多的水。

备注:你不必倾倒容器。


3.超时的c++算法

当然,谁都可以想到的解法就是暴力匹配,当遇到等差数列的时候当然就超时了!!!

这里写图片描述

// leetcode11.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<vector>
using namespace std;


int maxArea(vector<int>& height)
{
    int max = 0;
    if (height.size() == 0) return 0;

    int length = height.size();
    int area = 0;
    for(int i=0;i<length;i++)
    {
        for (int j = i; j < length; j++)
        {
            int high = height[j] > height[i]?height[i]:height[j];
            area = high*(j - i);
            if (max<area)
            {
                max = area;

            }
        }

    }


    return max;
}
int main()
{
    vector<int> array(10);
    array.push_back(1);
    array.push_back(1);

    int area = maxArea(array);
    return 0;
}

4.正确答案

这里写图片描述

算法证明:

Here is the proof.
Proved by contradiction:

Suppose the returned result is not the optimal solution. Then there must exist an optimal solution, say a container with a_ol and a_or (left and right respectively), such that it has a greater volume than the one we got. Since our algorithm stops only if the two pointers meet. So, we must have visited one of them but not the other. WLOG, let’s say we visited a_ol but not a_or. When a pointer stops at a_ol, it won’t move until

The other pointer also points to a_ol.
In this case, iteration ends. But the other pointer must have visited a_or on its way from right end to a_ol. Contradiction to our assumption that we didn’t visit a_or.

The other pointer arrives at a value, say a_rr, that is greater than a_ol before it reaches a_or.
In this case, we does move a_ol. But notice that the volume of a_ol and a_rr is already greater than a_ol and a_or (as it is wider and heigher), which means that a_ol and a_or is not the optimal solution – Contradiction!

Both cases arrive at a contradiction.

参考答案:

///C++

int maxArea(vector<int>& height) {
    int water = 0;
    int i = 0, j = height.size() - 1;
    while (i < j) {
        int h = min(height[i], height[j]);
        water = max(water, (j - i) * h);
        while (height[i] <= h && i < j) i++;
        while (height[j] <= h && i < j) j--;
    }
    return water;
}
///C语言参考答案

A bit shorter and perhaps faster because I can use raw int pointers, but a bit longer because I don't have min and max.

int maxArea(int* heights, int n) {
    int water = 0, *i = heights, *j = i + n - 1;
    while (i < j) {
        int h = *i < *j ? *i : *j;
        int w = (j - i) * h;
        if (w > water) water = w;
        while (*i <= h && i < j) i++;
        while (*j <= h && i < j) j--;
    }
    return water;
}

python参考答案

class Solution:
    def maxArea(self, height):
        i, j = 0, len(height) - 1
        water = 0
        while i < j:
            water = max(water, (j - i) * min(height[i], height[j]))
            if height[i] < height[j]:
                i += 1
            else:
                j -= 1
        return water

我的完整工程:

// leetcode11.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<vector>
using namespace std;

///超时了
int maxArea(vector<int>& height)
{
    int max = 0;
    if (height.size() == 0) return 0;

    int length = height.size();
    int area = 0;
    for(int i=0;i<length;i++)
    {
        for (int j = i; j < length; j++)
        {
            int high = height[j] > height[i]?height[i]:height[j];
            area = high*(j - i);
            if (max<area)
            {
                max = area;

            }
        }

    }


    return max;
}

///accept
int maxArea2(vector<int>& height)
{
    int max = 0;
    if (height.size() == 0) return 0;

    int length = height.size();
    int area = 0;
    int l = 0;
    int r = length - 1;

    while (l < r)
    {
        int high = height[l] > height[r] ? height[r] : height[l];
        max = max > (high * (r - l)) ?  max : (high * (r - l));
        if (height[l] < height[r])
            l++;
        else
            r--;
    }

    return max;
}
int main()
{
    vector<int> array(0);
    array.push_back(1);
    array.push_back(1);

    int area = maxArea2(array);
    return 0;
}

相关文章
|
人工智能 容器
Leetcode 11. Container With Most Water
题目可以这么理解,在i位置有条高为ai的竖线,让你选出两台竖线构成一个容器,使得该容器装的水最多,注意容器不能倾斜。
47 3
Leetcode 365. Water and Jug Problem
一句话理解题意:有容积为x和y升的俩水壶,能不能量出z升的水。 我刚开始看到这题,立马就想了下暴力搜索的可能性,但考虑了下数据大小,立马放弃这个暴力的想法,于是意识到肯定有比较简单的数学方法,其实我自己没想到,后来看还是看了别人的代码,很多博客都直接给出了解法, 但没介绍为什么能这么解。所以我决定解释下我自己的思路。
48 0
LeetCode 417. Pacific Atlantic Water Flow
给定一个 m x n 的非负整数矩阵来表示一片大陆上各个单元格的高度。“太平洋”处于大陆的左边界和上边界,而“大西洋”处于大陆的右边界和下边界。 规定水流只能按照上、下、左、右四个方向流动,且只能从高到低或者在同等高度上流动。 请找出那些水流既可以流动到“太平洋”,又能流动到“大西洋”的陆地单元的坐标。
109 0
LeetCode 417. Pacific Atlantic Water Flow
LeetCode 407. Trapping Rain Water II
我们把最外面的四边当成四面墙,想象海水面不断的升高,首先会浸过墙面最低的格子,如果墙面最低格子的四周(出了在墙面的格子)有比它矮的格子,那么这就可以形成一个蓄水池,蓄水池的最高高度就是墙面最低的格子,于是我们计算这个蓄水池可以获得的蓄水量;然后这个蓄水池被添加到墙面中;继续在墙面中找最低的格子;
98 0
LeetCode 407. Trapping Rain Water II
|
索引
LeetCode 42 Trapping Rain Water
给定n个非负整数,每个非负整数表示一个宽度为1的柱子,计算下雨后能够捕获多少水.
71 0
LeetCode 42 Trapping Rain Water
|
机器学习/深度学习 PHP 索引
[Leetcode 之 PHP 解析 (42. Trapping Rain Water)
[Leetcode 之 PHP 解析 (42. Trapping Rain Water)
106 0
[Leetcode 之 PHP 解析 (42. Trapping Rain Water)
|
容器
Leetcode-Medium 11. Container With Most Water
Leetcode-Medium 11. Container With Most Water
98 0
Leetcode-Medium 11. Container With Most Water
|
数据库
LeetCode(数据库)- The Airport With the Most Traffic
LeetCode(数据库)- The Airport With the Most Traffic
127 0
LeetCode - 42. Trapping Rain Water
42. Trapping Rain Water  Problem's Link  ---------------------------------------------------------------------------- Mean:  在坐标上给你一些竖直放置的条形积木,问你这个积木能够容纳多少液体.
898 0