[LeetCode] 11. 最も多くの水を入れる容器。難易度:中程度。ダブルポインタのソリューションについては、詳しく研究する価値があります。


[LeetCode] 11. 最も多くの水を入れる容器。難易度:中程度。

1. トピック

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0)(i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。

ここに画像の説明を挿入
ここに画像の説明を挿入

2. 私の解決策: ダブル for ループ、制限時間を超過する

最も簡単に考えられるのは暴力的なループで、二重の for ループはすべての状況を横断して最大値を取得します。時間計算量は O(n^2) で、制限時間を超えています。コード:

class Solution {
    
    
public:
    int max(int a,int b){
    
    
        return a>b?a:b;
    }
    int min(int a,int b){
    
    
        return a<b?a:b;
    }

    int maxArea(vector<int>& height) {
    
    
        int length=height.size();
        int maxWater=0;
        for(int i=0;i!=length-1;i++)
            for(int j=i+1;j!=length;j++){
    
    
                maxWater=max(maxWater,min(height[i],height[j])*(j-i));
            }
        return maxWater;
    }
};

3. 最適な解決策: ダブル ポインターが両側から移動する

長方形の面積は、次の 2 つの要素に関係します。

(1) 長方形の長さ: 2 本の直線の間の距離
(2) 長方形の幅: 2 本の直線のうち短い方の長さ

したがって、長方形の面積を最大化するには、2 本の垂直線の間の距離をできるだけ長くし、2 本の垂直線の最短の長さをできるだけ長くする必要があります。

配列の左端と右端をそれぞれ指すように、左右の 2 つのポインターを設定します。このとき、2つの直線の間の距離が最も遠いので、次の長方形の面積が現在の面積より大きい場合は、高さ[左]と高さ[右]のうち短い方の直線を右に移動する必要があります。真ん中の長い直線が見つかるかどうかを確認します。

コード:

class Solution {
    
    
public:
    int max(int a,int b){
    
    
        return a>b?a:b;
    }
    int min(int a,int b){
    
    
        return a<b?a:b;
    }

    int maxArea(vector<int>& height) {
    
    
        const int length=height.size();
        int left=0;
        int right=length-1;
        int maxWater=0;
        while(left<right){
    
    
            maxWater=max(maxWater,min(height[left],height[right])*(right-left));
            if(height[left]<height[right])
                left++;
            else
                right--;
        }
        return maxWater;
    }
};

おすすめ

転載: blog.csdn.net/qq_43799400/article/details/130956526