Blue Bridge Cup を使い始めるには説得力があります (18) 部分文字列を最小限にカバーする (スライディング ウィンドウ ソリューション)

ようこそ ===フォロー===いいね=== コメントして、一緒に学び、一緒に進歩しましょう!

------Lanqiao Cupエントリーの一連のアルゴリズム例を更新し続けます-------

Java とアルゴリズムも好きな方は、ぜひコラムに登録して、一緒に学び、コミュニケーションしてください。

あなたのいいね、注目、コメントが私の創作の原動力です!

-------私の記事がお役に立てば幸いです-------

前書き:春節の前後に個人的な理由により、継続的な更新はありませんでした. 学校が始まったので、さまざまなアルゴリズムソリューションが着実に更新されます. 4月には、ブルーブリッジカップ大会が開催されます. 時間は待ちません. 、一緒に進歩しましょう!希望に満ちた若いうちに頑張りましょう!

1. トピックの説明

s文字列、文字列   が与えられますtのすべての文字をカバーする最小の部分文字列sを返しますすべての文字をカバーする部分文字列がに存在しない場合は、t空の文字列を返しますst""

例 1:

入力: s = "ADOBECODEBANC", t = "ABC"
出力: "BANC"
説明:最小カバー部分文字列 "BANC" には、文字列 t の 'A'、'B'、および 'C' が含まれています。

例 2:

入力: s = "a", t = "a"
出力: "a"
説明:文字列 s 全体が最小の部分文字列です。

例 3:

入力: s = "a", t = "aa"
出力: ""
説明: t の 2 文字 'a' は s の部分文字列に含まれる必要があるため、
条件を満たす部分文字列はなく、空の文字列です返されます。

2. アイデアと解決策

  この質問はLikouには難しいです. 私が書いたアルゴリズムは最後のテストケースに合格できませんでした. 明らかに時間の複雑さが高すぎてタイムアウトになったので、他の大物の方法を参照して書き直しました. 次に,私はそれについて話します.私の考えについて話してください.

1. この問題は、部分文字列が繰り返される 2 つの文字列を照合することです. まず、2 つの文字列を文字配列に変換すると、toCharArray() を実装できます。

2. HashMap ハッシュ テーブルを使用して、各文字の出現回数をカウントします。

3. 間隔が [左、右) のスライディング ウィンドウを決定し、まず文字配列 t を Target に入れ、同じ文字が一致した場合は、その文字を Window (スライディング ウィンドウ) に追加します。つまり、右++、ウィンドウのプロセス拡張

4. トラバーサル後、スライディング ウィンドウ内のValid の文字数がTarget と一致する場合、それは修飾された部分文字列であり、レコード長は Len です。

5.ウィンドウが移動を開始し、左++ になり、最初の文字を削除し、ウィンドウが条件を再度満たしているかどうかを検証します。満たしていない場合は、Vaild-1.

6. 親番号 Valid が Target と再び一致するまで部分文字列の長さの比較を実行し、最後にウィンドウの右端が境界に触れて最短の部分文字列を取得します。

3. 参照コード

  public String minWindow(String s, String t) {
        char[] T = t.toCharArray();
        char[] S = s.toCharArray();
        Map<Character, Integer> Window = new HashMap<>();
        Map<Character, Integer> Target = new HashMap<>();//匹配目标
        int left = 0, right = 0, start = 0;
        int Valid = 0, Len = Integer.MAX_VALUE;//默认设为最大值

        for (char ch : T) Target.put(ch, Target.getOrDefault(ch, 0) + 1);//将t字符串放入哈希表
        while (right < s.length()) {
            char ch = S[right];
            right++;
            if (Target.containsKey(ch)) {
                Window.put(ch, Window.getOrDefault(ch, 0) + 1);
                if (Target.get(ch).equals(Window.get(ch)))
                    Valid++;//匹配到相同字母累加计算
            }
            while (Valid == Target.size()) {//当目标字母全部都包含在s中时
                if (right - left < Len) {
                    start = left;
                    Len = right - left;
                }
                char d = S[left];
                left++;//窗口左移,开始收缩
                if (Target.containsKey(d)) {
                    Window.put(d, Window.get(d) - 1);
                    if (Window.get(d) < Integer.valueOf(Target.get(d)))
                    {
                        Valid--;
                    }
                }
            }
        }
        return Len == Integer.MAX_VALUE ? "" : s.substring(start, start + Len);
    }

投稿するのは簡単ではありません。大物に手を挙げてもらいたいです。


いいね: いいねは一種の美徳であり、上司による私の作成の認識です!


コメント:ホワイトコンタクトはありません、あなたと私のコミュニケーションの始まりです!


コレクション: もっと選んでくれませんか、それは私への上司の感謝です!

おすすめ

転載: blog.csdn.net/m0_55278347/article/details/129147828