
1.题目解析
1.该题"讲人话"就是在一个字符串s中找到一个最短的能够涵盖子串所有字符的子串
2.解法
- 解法1(暴力枚举+hash表)
cpp
class Solution {
public:
string minWindow(string s, string t) {
int m = s.size();
int n = t.size();
if (m < n)
return ""; // 解决实例3的特殊情况
unordered_map<char, int> need; // 统计t中的字符需要的次数
for (auto c : t) {
need[c]++;
}
int required = need.size(); // 记录字符种类
int len = INT_MAX;
int start = 0; // 记录子串开始位置为后续返回字符串奠定基础
for (int i = 0; i < m; i++) {
int matched = 0;
unordered_map<char, int> window;
for (int j = i; j < m; j++) {
char c = s[j];
if (need.count(c)) { // 筛除不必要的元素
window[c]++; // 记录子串中字符出现次数
if (window[c] == need[c])
matched++; // 达到目标
}
if (matched == required) {
int currentlen = j - i + 1;
if (currentlen < len) {
len = currentlen;
start = i; // 更新位置
}
break;
}
}
}
return len == INT_MAX ? "" : s.substr(start, len);
}
};
虽然这种解题方法容易想但是作为一道困难题是绝对不可能让你暴力(O(n^2))过的,这个时候我们就需要在暴力的基础上进行优化
我们此处可以选择使用滑动窗口的方式对该问题进行优化

- 解法2(滑动窗口+手动hash)
cpp
class Solution {
public:
string minWindow(string s, string t) {
int hash1[128] = {0}; // 统计t内字符出现的次数
int kinds = 0;//统计有效字符个数
for (auto ch : t) {
if (hash1[ch]++ == 0)
kinds++;
}
int hash2[128] = {0};
int minlen = INT_MAX, begin = -1;
for (int left = 0, right = 0, count = 0; right < s.size(); right++) {
char in = s[right];
if (++hash2[in] == hash1[in])//进窗口加维护count
count++;
while (count == kinds) {//判断
if (right - left + 1 < minlen) {//更新结果
minlen = right - left + 1;
begin = left;
}
char out = s[left++];//出·窗口维护count
if (hash2[out]-- == hash1[out])
count--;
}
}
if (begin == -1)
return "";
else
return s.substr(begin, minlen);
}
};