1. 程式人生 > >Leetcode 11. Container With Most Water 盛最多水的容器 解法

Leetcode 11. Container With Most Water 盛最多水的容器 解法

題目如下:

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

The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.

Example:

Input: [1,8,6,2,5,4,8,3,7]
Output: 49

個人比較菜,第一反應DP,但發現這個DP沒什麼聯絡。。。。

解法1:

 最直接的暴力匹配

時間複雜度:O(n^2)

空間複雜度:O(1)

解法2:

雙指標法

雙指標法的一個典型例題就是283. Move Zeroes

考慮該問題,結果矩形的大小為 (x2 - x1)* min(height(x1)height(x2));

那麼當x2-x1 增大時,即x1不變x2增大或x2不變,x1增小時,通俗的來說就是2個指標從中心向2邊擴散增加底部寬度,但這種方式需要確定起始的中心點在哪,而且會存在有一邊掃描不到的情況,此外,無法確定到底是向左還是向右擴散

那麼考慮從兩邊向中心聚攏,這種情況下有一種很確定的情況,那就是當向內縮小的方向的height值大時,總的面積大小肯定是減小的,因為高度取決於height中最小的那個,而底部寬度是在不斷減小的,那麼只需要每次將height值最小的方向向內縮小即可,並且此方法可保證掃描到所有情況

程式碼如下:

class Solution {
public:
    int maxArea(vector<int>& height) {
        int maxVal = 0;
        int left = 0;
        int right  = height.size()-1;
        while(left!=right)
        {
            int maxHeight = min(height[right],height[left]);
            maxVal = max((right- left)*maxHeight,maxVal);
            if(height[left]>height[right])
                --right;
            else
                ++left;
            
        }
        
        return maxVal;
    }
};