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;
    }
};
相關文章
相關標籤/搜索