题目
代码(首刷看解析)
滑动窗口
在做这道题的时候,遇到了一件特别fxxk的事情。就是当我在进行while判断的时候, while(r < int(s.size())),一开始没有加int,所以一直没找到bug,气死我了。后来查资料发现,当有符号数和无符号数比较的时候,有符号数会转换为无符号数,而负数转换为无符号数会变得特别大(最高位是1),所以就出现了错误。。。
class Solution {
public:
unordered_map<char, int> need, window;
string minWindow(string s, string t) {
for(const auto& c : t) {
++need[c];
}
int l = 0, r = -1;
int ansl = -1, len = s.size()+1;
while(r < int(s.size())) {
if(need.find(s[++r]) != need.end()) { // 是t中的字符
++window[s[r]]; // 加入window
}
while(check() && l <= r) { // 判断是否需要移动窗口
if(r - l + 1 < len) {
ansl = l;
len = r - l + 1;
}
if(need.find(s[l]) != need.end()) {
--window[s[l]];
}
l++;
}
}
return ansl == -1 ? "" : s.substr(ansl, len);
}
bool check() {
for(const auto& p : need) {
if(window[p.first] < p.second)
return false; // 不需要移动窗口
}
return true; // 已经包含全部字符串,需要移动窗口
}
};
代码(二刷看解析)
class Solution {
public:
string minWindow(string s, string t) {
unordered_map<char, int> need, window;
for(char& c : t) {
need[c]++;
}
int start = 0;
int left = 0, right = 0;
int valid = 0; // 判断是否覆盖全部子串
int len = INT_MAX;
while(right < s.size()) {
char c = s[right];
if(need.count(c)) {
window[c]++;
if(window[c] == need[c]) {
valid++;
}
}
right++;
while(valid == need.size()) {
if(right - left < len) {
start = left;
len = right - left;
}
char d = s[left];
left++;
if(window.count(d)) {
if(window[d] == need[d])
valid--;
window[d]--;
}
}
}
return len == INT_MAX ? "" : s.substr(start, len);
}
};
代码(7.31 三刷调试看解析)
牢记第四个问题:我们要的结果应该在扩大窗口时更新还是在缩小窗口时更新?: 由于我们这里要的是能覆盖目标子串的最小长度,所以应该在缩小时更新,也就是在left左移的上面更新结果。
这次的问题出在:1. 不知道在哪更新答案:应该在进行窗口缩减的时候更新
2. 需要将if(window[c] == need[c])
的判断放到if(need.count(c))
里面
class Solution {
public:
string minWindow(string s, string t) {
unordered_map<char, int> window, need;
for(char& c : t)
need[c]++;
int left = 0, right = 0;
int len = INT_MAX, start = 0;
int count = 0;
while(right < s.size()) {
char c = s[right];
right++;
if(need.count(c)) {
window[c]++;
if(window[c] == need[c]) // 这个判断需要放到里面来,因为只有c存在的时候,才能进行判断,否则使用need[c]会创建新的
count++;
}
while(count == need.size()) {
if(right - left < len) {
len = right - left;
start = left;
}
char d = s[left];
left++;
if(window.count(d)) {
if(window[d] == need[d])
count--;
window[d]--;
}
}
}
return len == INT_MAX ? "" : s.substr(start, len);
}
};
代码(8.30 四刷自解)
class Solution {
public:
string minWindow(string S, string T) {
unordered_map<char, int> need, window;
for(char& t : T)
need[t]++;
int left = 0, right = 0;
int valid = 0;
int len = INT_MAX, index = 0;
while(right < S.size()) {
char c = S[right];
right++;
if(need.count(c)) {
window[c]++;
if(window[c] == need[c])
valid++;
}
while(valid == need.size()) {
if(right - left < len) {
len = right - left;
index = left;
}
char d = S[left];
left++;
if(need.count(d)) {
if(window[d] == need[d])
valid--;
window[d]--;
}
}
}
return len == INT_MAX ? "" : S.substr(index, len);
}
};