[Leetcode] 567.文字列内の順列(スライディングウィンドウ)[中]

リンク

https://leetcode-cn.com/problems/permutation-in-string/

時間がかかる

問題解決:24分
問題解決:15分

題名

2つの文字列s1とs2が与えられた場合、s2にs1の順列が含まれているかどうかを判別する関数を記述します。

言い換えると、最初の文字列の順列の1つは、2番目の文字列の部分文字列です。

注意:

  • 入力文字列には小文字のみが含まれます
  • 両方の文字列の長さは[1、10,000]の間です

アイデア

s1の長さがmで、s2の長さがnであるとします。

固定長mのスライディングウィンドウを設定し、s2でウィンドウをスライドさせ、現在のスライディングウィンドウの26個の小文字の数を毎回カウントし、現在のウィンドウの26個の小文字の各文字の数がs1の26に等しい各小文字の各文字の数は等しいです。等しいスライドウィンドウがある場合は、s1の配置であるs2のサブストリングがあることを意味します。trueを返します。それ以外の場合は、ウィンドウを後方にスライドします。ウィンドウがs2で最後までスライドし、そのような部分文字列が見つからない場合は、falseを返します。

時間計算量:O(n)O(n)O n

ACコード

class Solution {
    
    
public:
    bool check(vector<int>& s1cnt, vector<int>& s2cnt) {
    
    
        for(int i = 0; i < 26; ++i) {
    
    
            if(s1cnt[i] != s2cnt[i]) {
    
    
                return false;
            }
        }
        return true;
    }
    
    bool checkInclusion(string s1, string s2) {
    
    
        int m = s1.size();
        int n = s2.size();
        if(m > n) return false;
        
        vector<int> s1cnt(26, 0);
        vector<int> s2cnt(26, 0);
        for(auto c : s1) {
    
    
            s1cnt[c-'a']++;
        }

        // [l, r]
        int l = 0, r = 0;
        for(r = 0; r < m-1; ++r) {
    
    
            s2cnt[s2[r]-'a']++;
        }
        while(r < n) {
    
    
            s2cnt[s2[r]-'a']++;
            if(check(s1cnt, s2cnt)) {
    
    
                return true;
            }
            s2cnt[s2[l]-'a']--;
            l++;
            r++;
        }
        return false;
    }
};

おすすめ

転載: blog.csdn.net/Krone_/article/details/113780910