7 Container With Most Water_Leetcode

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.spa

这题O(n^2)的解法就是基本的暴力法。可是要想出O(n)的解法并不容易(实际上我就想不出来T_T),面试碰到这样难度的新题估计就跪了。orm

虽然有点悲观,可是解题的思路仍是有迹可循的。blog

container的面积由两个因素组成,一个是高度,一个是宽度。get

咱们一样采用的是“按序枚举”的思路,高度是不肯定的变量,很差枚举,可是宽度则是由1到n-1的肯定的量,能够很方便的枚举。it

此外,如同上题Candy,这种按序枚举的思路也能够是从左到右,从右往左等。io

在想到对宽度进行枚举后,这种枚举有两种,一个是从小往大,另外一个是从大往小。form

若是咱们想从小往大枚举,这种通常必须有dp的规律才可以使解法更优,可是从本题来看,每个解都只与左右两个index有关,并不包含子问题。因此从小往大的枚举不可行。class

那么从大往小枚举,好比3,2,5,4,1。最大的宽度,就是从3到1,这时咱们能够算出一个面积。当咱们缩小这个宽度,有两种方法,可是实际上只有右区间缩小一个可能获得最优解。为何呢?由于每次对于左右边界中较小的那一个,当前的宽度都是最宽的,也就是它能达到的最大面积了。变量

由此咱们能够只往一个方向进行左右边界的缩小,最终获得的方法是O(n)的。

Code:

class Solution {
public:
    int maxArea(vector<int> &height) {
        int n = height.size();
        if(n < 2) return 0;
        int res = 0;
        
        int left = 0, right = n-1;
        while(left < right)
        {
            int tmp = min(height[left], height[right]) * (right - left);
            if(tmp > res) res = tmp;
            
            if(height[left] < height[right]) left++;
            else right--;
        }
        return res;
    }
};
相关文章
相关标签/搜索