链接
https://leetcode-cn.com/problems/permutation-in-string/
耗时
解题:24 min
题解:15 min
题意
给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。
换句话说,第一个字符串的排列之一是第二个字符串的子串。
注意:
- 输入的字符串只包含小写字母
- 两个字符串的长度都在 [1, 10,000] 之间
思路
假设:s1 的长度为 m,s2 的长度为 n。
设置一个固定长度为 m 的滑动窗口,在 s2 上滑动窗口,每次统计当前滑动窗口内 26 个小写字母的数量,并检查当前窗口内 26 个小写字母中每个字母的数量是否和 s1 的 26 个小写字母中每个字母的数量都相等,如果存在都相等的滑动窗口则说明存在一个 s2 的子串是 s1 的排列,返回 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;
}
};