【LeetCode Hot 100】11. 盛最多水的容器

随机生成一个id發表於2024-09-20

題目描述

首先記錄一下題目的解法。使用雙指標記錄容器的邊界,從邊界最大的容器開始,i位於最左側,j位於最右側。每次向中間移動高度較小的那個指標,並使用一個變數res記錄容器最大的容積(即最終的答案)。

// C++
class Solution {
public:
    int maxArea(vector<int>& height) {
        int i = 0, j = height.size() - 1;
        int res = 0;
        while (i < j) {
            int area = (j - i) * min(height[i], height[j]);
            res = max(res, area);
            if (height[i] < height[j]) {
                i++;
            } else {
                j--;
            }
        }
        return res;
    }
};

// Java
class Solution {
    public int maxArea(int[] height) {
        int i = 0, j = height.length - 1;
        int res = 0;
        while (i < j) {
            int area = j - i;
            if (height[i] < height[j]) {
                area *= height[i];
                res = Math.max(res, area);
                i++;
            } else {
                area *= height[j];
                res = Math.max(res, area);
                j--;
            }
        }
        return res;
    }
}

官方的題解中解釋了這種做法的正確性。我在這裡記錄一下我的直觀想法。對於這種題目,最粗暴的想法自然是使用雙重迴圈遍歷每一種邊界下標組合,記錄最大的那個答案,顯然對於較大的資料量來說,這種做法的時間複雜度為平方級,很容易超時。那麼我們該如何進行剪枝,跳過一些情況的判斷呢?將兩個指標放在最遠的兩端開始向中間靠攏,\(S=(j-i) \times min(h_i, h_j)\),當指標向中間移動時,第一個乘數項一定變小,要想讓整體的面積(容器的容積)變大,第二個乘數就只能變大,如果我們移動高度較大的那個指標(假設height[i] < height[j],我們移動j),\(min(h_i,h_j)\)這一項仍然由高度較小(即iheight[i])的那一項決定,也就是說移動高度較大的指標不會使這一項變大,當且僅當我們移動高度較小的那個指標時,才有可能使得此項變大。這也是為什麼我們每次移動其中一個指標的原因。

相關文章