1. 程式人生 > >【LeetCode】11. Container With Most Water(盛最多水的容器)-C++實現的三種方法

【LeetCode】11. Container With Most Water(盛最多水的容器)-C++實現的三種方法

本題是Bloomberg的面試題。

問題描述:

 一、第一種方法-暴力解法

  當我們在面試時想不到解題的方法時,不妨使用暴力解法,雙重遍歷陣列。

當 i = 0 時,使用指標 j 遍歷陣列,找到第一輪的最大值 area:

當i = 2 ,使用指標 j 遍歷陣列,找到第二輪的最大值 area:

直到 指標 i 遍歷完成。 

實現程式碼:

class Solution {
public:
    int maxArea(vector<int>& height) {

        assert(height.size() >= 2);

        int area = 0;
        for(int i = 0 ; i < height.size() ; i ++)
            for(int j = i + 1; j < height.size() ; j ++)
                area = max(area , min(height[i], height[j]) * (j - i));
        return area;
    }
};

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

空間複雜度:O(1)

第二種方法:對撞指標法

分別在頭、尾元素定義兩個指標 l , r ;

如圖所示,遍歷陣列,直到兩個指標相遇,停止迴圈 

實現程式碼:

/// Two Pointers
/// Time Complexity: O(n)
/// Space Complexity: O(1)
class Solution {
public:
    int maxArea(vector<int>& height) {

        assert(height.size() >= 2);

        int l = 0, r = height.size() - 1;
        int area = 0;
        while(l < r){
            area = max(area , min(height[l], height[r]) * (r - l));
            if(height[l] < height[r])
                l ++;
            else
                r --;
        }
        return area;
    }
};

第三種方法:對撞指標法的優化

首先,使用第一個和最後一行來評估最寬的容器。所有其他可能的容器都不那麼寬,所以要有更多的水,它們需要更高。因此,在評估了最寬的容器之後,在兩端都跳過不支援更高高度的線。然後評估我們到達的新容器。重複,直到不再有可能的容器。

 實現程式碼:

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;
}

分析:

①  i = 0, j = 9

 water = 1 * (9 - 0) = 9; 

i ++;   j 不變;

 ② i = 1, j = 8;

water = max(49, 7 *  7) = 49;

然後 j--;

 ③ i = 1, j = 7;

water = max(49, 3 *  6) = 49;

然後 j  -- ;

 ④ i = 1, j =6;

water = max(49, 5 *  8) = 49;

然後 j -- ;

 ⑤ i = 2, j =5;

water = max(49, 3 * 4) = 49;

然後 j -- ;

⑥ i = 2, j =4;

water = max(49, 2 * 5) = 49;

然後 j -- ;

⑦ i = 2, j =3;

water = max(49, 2 * 1) = 49;

然後 j -- ;

兩個指標相遇,完成整個遍歷過程。

參考資料: