目录
438. 找到字符串中所有字母异位词
解析
题解
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
// 014_专题二_滑动窗口_找到字符串中所有字母异位词_C++
vector<int> ret;
int hash1[26] = {0}; // 统计p字符串里面的字母
for (auto ch : p) hash1[ch - 'a']++;
int hash2[26] = {0}; // 统计滑动窗口里面的字母
int m = p.size(); // p里面的有效字符
for (int left = 0, right = 0, count = 0; right < s.size(); ++right) // count统计滑动窗口中的有效字符的个数
{
char in = s[right]; // 进窗口的元素
if (++hash2[in - 'a'] <= hash1[in - 'a']) count++; // 进窗口 + 维护count
if (right - left + 1 > m) // 判断是否需要出窗口
{
char out = s[left++]; // 出窗口元素 + left 向后移动
if (hash2[out - 'a']-- <= hash1[out - 'a']) count--; // 有效字符维护 count-- + 出窗口
}
if (count == m) // 判断是否是合法的异位词
ret.push_back(left);
}
return ret;
}
};
30. 串联所有单词的子串
解析
题解
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
// 结合 014_专题二_滑动窗口_找到字符串中所有字母异位词_C++ 思考
vector<int> ret;
unordered_map<string, int> hash1; // 统计words里面的子串
for (auto& s : words)
hash1[s]++;
int len = words[0].size(); // 每个单词的长度
int m = words.size(); // words里面子串的个数
for (int i = 0; i < len; ++i) // 执行len次滑动窗口的执行
{
unordered_map<string, int> hash2; // 统计滑动窗口里面的子串
for (int left = i, right = i, count = 0; right + len <= s.size(); right += len) {
// 进窗口 + 维护count
string in = s.substr(right, len);
hash2[in]++;
if (hash1.count(in) && hash2[in] <= hash1[in])
count++;
// 判断
if (right - left + 1 > len * m) // +1 就可以保证长度超过了words里面的长度
{
// 出窗口 + 维护count
string out = s.substr(left, len);
if (hash1.count(out) && hash2[out] <= hash1[out]) count--;
hash2[out]--;
left += len;
}
// 更新结果
if (count == m)
ret.push_back(left);
}
}
return ret;
}
};
76. 最小覆盖子串
解析
题解
class Solution {
public:
string minWindow(string s, string t) {
// 016_专题二_滑动窗口_最小覆盖子串_C++
int hash1[128] = { 0 }; // 统计t里面的字母个数
int kinds = 0; // t里面字母的种类
int hash2[128] = { 0 }; // 统计滑动窗口的字母出现的个数
for (auto& ch : t)
{
if (hash1[ch] == 0) kinds++;
hash1[ch]++;
}
int minlen = INT_MAX, begin = -1; // 长度 起始位置
for (int left = 0, right = 0, count = 0; right < s.size(); ++right)
{
char in = s[right]; // 进窗口字母
hash2[in]++;
if (hash2[in] == hash1[in]) count++;
while (count == kinds) // 判断条件
{
// 更新结果
if (right - left + 1 < minlen)
{
minlen = right - left + 1;
begin = left;
}
char out = s[left]; // 出窗口字母
left++;
if (hash2[out] == hash1[out]) count--;
hash2[out]--;
}
}
if (begin == -1) return "";
return s.substr(begin, minlen);
}
};