[リコウ] 週次ゲーム 354 試合目 (正当な最長部分文字列の長さ)

トピック: 6924. 有効な最長部分文字列の長さ

文字列ワードと禁止された文字列の配列が与えられます。

文字列に禁止された文字列が含まれていない場合、この文字列は正当であると言います。

文字列 word の有効な最長部分文字列の長さを返してください。

部分文字列は、文字列内の文字の連続した期間を指し、空にすることもできます。

例 1:

入力: word = "cbaaaabc"、禁止 = ["aaa", "cb"]
出力: 4
説明: 有効な部分文字列は合計 9 つあります: "c"、"b"、"a"、"ba"、" aa" 、 "bc" 、 "baa" 、 "aab" および "aabc" 。有効な最長の部分文字列の長さは 4 です。
他のすべての部分文字列には、「aaa」または「cb」のいずれかが含まれます。

例 2:

入力: word = "leetcode"、forbidden = ["de", "le", "e"]
出力: 4
説明: 有効な部分文字列は合計 11 個あります: "l"、"t"、"c"、" o " 、 "d" 、 "tc" 、 "co" 、 "od" 、 "tco" 、 "cod" および "tcod" 。有効な最長の部分文字列の長さは 4 です。
他のすべての部分文字列には、「de」、「le」、および「e」の少なくとも 1 つが含まれます。

ヒント:

1 <= word.length <= 1e5
word には小文字の英字のみが含まれます。
1 <=forbidden.length <= 1e5
1 <=forbidden[i].length <= 10fordid
[i] には小文字の英字のみが含まれます。

アイデア: ハッシュ テーブル + ダブル ポインター

部分文字列 l=0 の左端点を初期化し、部分文字列 r の右端点を列挙します。

たとえば 2 では、r ≥ 1 である限り、正当な部分文字列に le を含めることはできないため、左端点 l は右に移動する必要があり、0 に戻ることはできません (そうしないと le が含まれてしまいます)。左のエンドポイントは右にのみ移動し、左には移動しないため、この単調性によりアルゴリズムの効率が保証されます。

r が新しい文字に右に移動するとき、その文字を右端として、forbidden[i] の最短の長さを列挙します。word[i] から word[right] までの部分文字列が禁止されていることが判明した場合 (ハッシュ テーブルで実装)、l =i+1 を更新して列挙を終了します。これにより、正当な部分文字列に禁止された文字列が含まれるのを防ぎます。列挙が完了すると、答えは有効な部分文字列長の最大値 r −l +1 に更新されます。

ACコード:

class Solution {
public:
    int longestValidSubstring(string word, vector<string>& forbidden) 
    {
        unordered_set<string> s(forbidden.begin(),forbidden.end());
        int n=word.size();
        int l=0,ans=0;
        for(int r=0;r<n;r++)
        {
            for(int i=r;i>=l&&i>r-10;i--)
            {
                if(s.count(word.substr(i,r-i+1)))
                {
                    l=i+1;
                    break;
                }
            }
            ans=max(ans,r-l+1);
        }
        return ans;
    }
};

次の記事 最適なバリア(スタック)

Supongo que te gusta

Origin blog.csdn.net/weixin_74088105/article/details/131753089
Recomendado
Clasificación