11_乘最多水的容器

zeta186012發表於2024-08-17

11_乘最多水的容器

【問題描述】

給定一個長度為 n 的整數陣列 height 。有 n 條垂線,第 i 條線的兩個端點是 (i, 0)(i, height[i]) 。找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。返回容器可以儲存的最大水量。說明:你不能傾斜容器。

示例一:
輸入:[1,8,6,2,5,4,8,3,7]
輸出:49 
解釋:圖中垂直線代表輸入陣列 [1,8,6,2,5,4,8,3,7]。在此情況下,容器能夠容納水(表示為藍色部分)的最大值為 49。

示例二:
輸入:height = [1,1]
輸出:1

【演算法設計思想】

在解決本題時,筆者首先使用了較為常見的暴力解法,即遍歷一遍陣列,但是當資料一大就會超出了時間的限制,暴力解法的時間複雜度達到了O(n^2),其效率是極其低下的。(原諒我是一個笨比😇。)
暴力解法的C++描述如下:

class Solution {
public:
    int maxArea(vector<int>& height) {
        int n = height.size();
        int answer = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                int width = j - i;
                int minHeight = height[i] < height[j] ? height[i] : height[j];
                answer = answer < width * minHeight ? (width * minHeight) : answer;
            }
        }
        return answer;
    }
};

好了,接下來讓我們步入正軌,開始講解正確的解法:
本題分治法,動態規劃都不適用,要想得到O(n)的時間複雜度,只能夠使用雙指標法。這裡我們要注重縮減搜尋空間這個思想。關鍵的思路在於,每次我們移動較短的那根柱子。(有點貪心的味道在其中了。)

【演算法描述】

C++:

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

Java:

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

Python:

class Solution:
    def maxArea(self, height: List[int]) -> int:
        size = len(height)
        area = 0
        result = 0
        i = 0
        j = size - 1
        while i < j:
            area = (j - i) * min(height[i],height[j])
            result = max(result,area)
            if(height[i] < height[j]):
                i = i + 1
            else:
                j = j - 1
        return result         

C語言:

int maxArea(int* height, int heightSize) {
    int area = 0;
    int result = 0;
    int i = 0;
    int j = heightSize - 1;
    while(i < j){
        int minHeight = height[i] < height[j] ? height[i] : height[j];
        area = (j - i) * minHeight;
        result = result < area ? area : result;
        if(height[i] < height[j]){
            i++;
        }else{
            j--;
        }
    }
    return result;
}

相關文章