アルゴリズムの最初の紹介 · スライディング ウィンドウ (1)

目次

 序文:

最小長の部分配列

質問分析

アルゴリズム原理

アルゴリズムの作成

繰り返しの長さを除いた最小の文字列

質問分析

アルゴリズム原理

アルゴリズムの作成


 序文:

この記事の冒頭で、スライディング ウィンドウ アルゴリズム タイプのトピックを紹介します。スライディング ウィンドウは実際にはダブル ポインターですが、前に紹介したダブル ポインターは相互に移動します。

スライディング ウィンドウは同じ方向に移動します。

この記事では、次の 2 つのトピックを通してスライディング ウィンドウの基本的な使い方を紹介します。

209. 最小長のサブ配列 - LeetCode

3. 繰り返し文字を含まない最長の部分文字列 - LeetCode

最初のステップは問題分析、第 2 ステップはアルゴリズムの原理、そして第 3 ステップはアルゴリズムの作成という 3 つのステップを通じて導入されます。では、問題分析の部分で暴力的な解決策があるかどうかを確認します。 、最初のステップの質問に進みます。


最小長の部分配列

質問分析

質問の要件は、間隔内の値の合計がターゲット以上になるような連続間隔を見つけることです。このタイプの間隔がある場合、戻り値は最小長である必要があります。この間隔。そのような部分配列がない場合は、0 を返す必要があります。

次に、例が 2 つあります。では、この問題を暴力的に解決することはできるのでしょうか?もちろん可能です。

この条件を満たすすべての区間を見つけてその長さを決定するだけで済みますが、時間計算量は間違いなく O(N^2) であり、この問題ではタイムアウトになるため、学生は試してみることができます。自分たちのもの。

では、一見するとこの質問ではスライディング ウィンドウが使用できるのはなぜでしょうか。

必要なのは連続したスペースであるため、経験則として、連続したスペースが必要な問題に遭遇した場合は、スライディング ウィンドウに頼ったほうがよいでしょう。

それでは、アルゴリズムの原理部分に入りましょう。

アルゴリズム原理

スライディング ウィンドウの本質は、2 つのポインターが同じ方向に移動することによって、間隔の合計が満たされているかどうかを判断し、満たされている場合は長さを比較することです。

では、引き違い窓を使ったらどうなるでしょうか?
最初は、2 つのポインターの開始点が同じである必要があります。2 つのポインターの位置が同じでない場合は、この間隔の合計を特定するために追加のループを追加する必要があるため、次のようになります。

int left = 0, right = 0;

これは間違いありません。スライディング ウィンドウの場合、2 つの名詞を覚えることができます。1 つは入口ウィンドウ、もう 1 つは出口ウィンドウです。いつウィンドウに入るのか、そして出口ウィンドウとは何かが、私たちのトピックです。

ウィンドウに入るということは、間隔の合計がターゲット未満であることを意味するため、より多くの数値を含める必要があります。このため、質問自体は正の整数を必要としません。したがって、数値が次のとおりであることを確認するだけで済みます。できるだけ大きく。

ウィンドウの外とは、間隔の合計 > ターゲットを意味します。ウィンドウの外に出て、内側に存在する最小の長さを判断するだけです。

基本原則はこれです。出入りすることで問題を解決できます。

アルゴリズムの作成

class Solution 
{
public:
    int minSubArrayLen(int target, vector<int>& nums) 
    {
        int ans = INT_MAX, left = 0, right = 0 ,sum = 0;
        for(;right < nums.size();right++)
        {
            sum += nums[right];
            while(sum >= target) 
            {
                ans = min(ans,right - left + 1);//如果ans为0 那么这一步永远都是0
                sum -= nums[left++];
            }
        }
        return ans == INT_MAX ? 0 : ans;
    }
};

しかし、この質問の嫌な点は、初期の長さが非常に大きな数値として定義されていない場合、判断して比較するときに最小の数値を min から取得できないため、ans を INT_MAX として定義する必要があることです。番号、大丈夫ですよ。

この時点で、トピックの分析は完了です。


繰り返しの長さを除いた最小の文字列

質問分析

質問は非常に短く、合格条件は文字が繰り返されない最長の文字列の長さを返すことです。したがって、文字については次のような要件があります。

したがって、重複があるかどうかを判断するには、何らかのマッピングがあるかどうかを判断するメソッドが必要です。ここではハッシュ マップを使用し、配列を使用してハッシュ テーブルを模倣します。質問の中に暴力が含まれているかどうかを判断することもできます。

これは存在する必要があります。2 つの for ループを使用します。2 番目のループは最後の要素を見つけて、マッピング値が 1 より大きいかどうかを判断します。1 より大きい場合は、その値を直接返すことができます。時間計算量は間違いなく O(N^2) であり、許容範囲内です。

ただし、この質問の性質は間隔であるため、スライディング ウィンドウを使用して回答することもできます。

アルゴリズム原理

前の質問のスライディング ウィンドウは、長さが最も小さい部分配列です。判定条件は >= target です。したがって、この質問の判定条件はハッシュ マップが 1 より大きいかどうかです。 :スライディング ウィンドウを使用した 3 つの質問があります。最初のステップはウィンドウに入ることであり、2 番目のステップは判断することであり、3 番目のステップはウィンドウから出ることです

以下の質問はすべて、この手順を非常に厳密に使用しています。

判定方法もハッシュマッピングを使用し、判定マッピングが1より大きい場合は出力が完了し、マッピングが条件を満たしている場合は対応するansが記録されます。も記録されます。

最後に、ans を返すだけです。

アルゴリズムの作成

class Solution 
{
public:
    int lengthOfLongestSubstring(string s) 
    {
        int hash[256] = { 0 }, ans = 0;
        for(int left = 0, right = 0;right < s.size();right++)
        {
            hash[s[right]]++;
            while(hash[s[right]] > 1)
            {
                hash[s[left++]]--;
            }
            ans = max(ans,right - left + 1);
        }
        return ans;
    }
};

引き違い窓の始まりが終わりました〜


読んでいただきありがとうございます!

おすすめ

転載: blog.csdn.net/2301_79697943/article/details/142713599