11. Contain with most water

11 contain with most water
Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) 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.

題目的意思即爲給定一組點,使其容積最大。
畫個圖示意一下
示意圖
每個非負整數類似於“水缸”的一條邊,an的值即爲邊的高度,每兩條邊與x軸組成一個“水缸”,要求出“水缸”能最多容納多少水。

最簡單的方法便是兩兩組成一個“水缸”,把每種可能性都算一次,進行比較,就能得出最多能容納多少水。
利用二重循環和比較來求得最大值,時間複雜度是On2
參考代碼如下:

class Solution {
public:
    int maxArea(vector<int>& height) {
        int max = 0;
        for(int i = 0; i < height.size(); i++) {
            for(int j = i + 1; j < height.size(); j++) {
                int calHeight = height[i];
                if(height[j] < height[h])
                    calHeight = height[j];
                int tempArea = calHeight * (j - i);
                if(tempArea > max)
                    max = tempArea;
            }
        }
        return max;
    }
};

當然這是過不了檢測的

O(n2) 的時間複雜度會使得當n很大的時候要花費相當多的時間來求解問題,效率並不高。

根據木桶原理,一隻木桶能盛多少水,並不取決於最長的那塊木板,而是取決於最短的那塊木板。這道題也是符合這個原理,“水缸”能裝多少水,兩條邊短的那一根的高度是一個很大的影響(決定了實際計算高度),同時“水缸”的寬度也會影響到能裝的水量。假設我們從兩端同時開始選中,先取最左和最右的兩根“木板”的情況,同時,在任意其他情況下,“水缸”的寬一定比這種情況小。爲了使得容量增加,只能移動“木板”搜尋其他情況,根據木桶原理,我們應當使得短的一邊變高,即爲,假設左邊的木板比右邊矮的時候,我們應該改變左邊的木板,往右搜尋是否有比目前最大容量還大的情況,而右邊高的木板則保留。當短的木板被“遺棄”,選擇往後搜索時,必然有很多種情況被排除。假如a0,a1,……,an,當前情況爲{a0, an},若a0 < an,此時a0→a1來尋找新的可能性,而被排除的{a0,a1},……,{a0,an-1},“水缸”的寬度一定小於{a0,an},而且高度被a0限制(a0爲上界),所以可以確定這些被排除的情況的水容量一定比{a0,an}小。所以我們只需要搜索一遍,以On 的時間複雜度便能得到結果。

參考代碼如下:

class Solution {
public:
    int maxArea(vector<int>& height) {
        int max = 0;
        int left = 0, right = height.size() - 1;
        while(left < right) {
            int calHeight = height[left];
            if(height[right] < height[left])
                calHeight = height[right];
            int contain = calHeight * (right - left);
            if(contain > max)
                max = contain;
            if(height[left] < height[right])
                left++;
            else
                right--;
        }
        return max;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章