leetcode-盛最多水的容器(c++)

機智的小陳今天學習了嗎發表於2020-12-07

題目

給你 n 個非負整數 a1,a2,…,an,每個數代表座標中的一個點 (i, ai) 。在座標內畫 n 條垂直線,垂直線 i 的兩個端點分別為 (i, ai) 和 (i, 0) 。找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。

說明:你不能傾斜容器。
在這裡插入圖片描述

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

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

示例 3: 輸入:height = [4,3,2,1,4] 輸出:16

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

提示: n = height.length 2 <= n <= 3 * 104 0 <= height[i] <= 3 * 104

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/container-with-most-water
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

思路

1.暴力破解法:使用二重迴圈算出每一種可能性,後選取最大面積。
2.雙指標法:
由於容器可以容納的最大面積是由短板決定的,可以得出面積公式為面積公式為:

S(i, j) = min(h[i], h[j]) × (j - i)

  • 無論是長板或者短板向內移動都會導致底邊長度(j-i)減小1
  • 若向內移動長板則min(h[i],h[j])不變,或減小,則s(i,j)將減小
  • 若向內移動短板則min(h[i],h[j])可能增大,s(i,j)可能增大

可以選取容器中的短板向內移動一格,可以有效的減少遍歷的次數且不丟失最大面積。

程式碼

  • 暴力法(超出時間限制)
class Solution {
public:
    int maxArea(vector<int>& height) {
        int area=0;
        int size=height.size();
        if(size<=1){
            return 0;
        }
        for(int i=0;i<size;i++){
            for(int j=i+1;j<size;j++){
                area = max(area,min(height[i],height[j])*(j-i));
            }
        }
        return area;
    }
};
  • 雙指標法(更優)
class Solution {
public:
    int maxArea(vector<int>& height) {
        int i=0;
        int j=height.size()-1;
        int area=0;
        while(i<j){
            if(height[i]<height[j]){
                area=max(area,height[i]*(j-i));
                i++;
            }else{
                area=max(area,height[j]*(j-i));
                j--;
            }
        }
        return area;
    }
};

相關文章