【Lintcode】383. Container With Most Water

題目地址:

https://www.lintcode.com/problem/container-with-most-water/description

給定一個數組AA,代表擋板的高度,選定兩個擋板,兩個擋板中間的區域可以看成一個水的盛具,其容積等於較矮的擋板的高度乘以寬度。要求返回最大容積。

思路是對撞雙指針,同時更新得到的容積。每次移動指針的時候,都選擇能產生更優解的方式。例如,兩個指針分別是llrr,當A[l]<A[r]A[l]<A[r]的時候,這個時候rr左移並不會得到更好的解(因爲盛具高度沒變,但底變窄了),所以此時右移ll;同理,當A[l]>A[r]A[l]>A[r]的時候要左移rr;而當A[l]=A[r]A[l]=A[r]的時候則需要同時移動兩個指針。代碼如下:

public class Solution {
    /**
     * @param heights: a vector of integers
     * @return: an integer
     */
    public int maxArea(int[] heights) {
        // write your code here
        if (heights == null || heights.length == 0) {
            return 0;
        }
        
        int res = 0;
        int l = 0, r = heights.length - 1;
        while (l < r) {
            res = Math.max(res, (r - l) * Math.min(heights[l], heights[r]));
            if (heights[l] > heights[r]) {
                r--;
            } else if (heights[l] < heights[r]) {
                l++;
            } else {
                l++;
                r--;
            }
        }
        
        return res;
    }
}

時間複雜度O(n)O(n),空間O(1)O(1)

算法正確性證明:
數學歸納法。當數組長度爲22時顯然成立。當數組長度爲nn的時候,由於當A[l]<A[r]A[l]<A[r]的時候,左擋板是ll的情況下的所有解都不可能超過A[l](rl)A[l](r-l),而A[l](rl)A[l](r-l)已經更新在res裏了,所以不需要枚舉左擋板是ll的情況了,將ll右移一位後,就得到了相同的但規模更小的問題,由歸納假設,算法可以得到正確答案,再和A[l](rl)A[l](r-l)比較一下即得到全局最優解。其他情況類似。

證明的本質是,將全局問題分爲兩類,即以ll爲左擋板和不以ll爲左擋板的兩類,然後分別的最優解合起來的更優解即爲全局最優解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章