leetcode Container With Most Water

来源:互联网 发布:沈阳筑巢seo 编辑:程序博客网 时间:2024/06/13 03:23

题目

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.
题目来源:https://leetcode.com/problems/container-with-most-water/

分析

若干根直线,求两根直线之间组成容器的最大容量。
首先,容器的高度取决于这两根线中较小的一根。与中间的线的高矮无关。
例如:1,2,1,3。当取2和3时,容量最大。
这道题和Largest Rectangle in Histogram是不一样的。

解法:

取left指针和right指针,从两头开始,往中间靠拢。如果靠拢的过程中发现height变小了就完全没必要算了,因为靠拢过程过程中宽度变小,如果高度再变小容量肯定变小。用两重循环直接暴力算也可以,复杂度是O(n^2)。

优化:

为了加快,可以先遍历一遍,暂存每个height右边第一个比它大的元素的下标,暂存每个height左边第一个比它大的元素的下标。这样双重循环是速度就能快一点。

代码

class Solution {public:    int maxArea(vector<int>& height) {        int n = height.size();        int *help_left = new int[n];        int *help_right = new int[n];        help_left[0] = -1;        help_right[n-1] = n;        for(int i = 1; i < n; i++){            int j = i-1;            while(height[i] > height[j] && j != -1)  j = help_left[j];            help_left[i] = j;        }        for(int i = n-2; i >= 0; i--){//这个也循环可以和上面的循环糅合成一个,一次遍历就可以了。            int j = i + 1;            while(height[i] > height[j] && j != n) j = help_right[j];            help_right[i] = j;        }        int max_area = 0;        for(int left = 0; left < n; ){            for(int right = n-1; right > left; ){                int h = min(height[left],height[right]);                int area = h * (right - left);                if(area > max_area)                    max_area = area;                if(help_left[right] > left)                    right = help_left[right];                else                    break;            }            if(help_right[left] < n)                left = help_right[left];            else                break;        }        return max_area;    }};
0 0