リンク
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;
}
};