题目描述
知识点
滑动窗口
结果
实现
码前思考
- 这道题目是我学习“滑动窗口”的例题,所以我没有对这道题目进行过独立的思考,是按照别人的思路写的;
代码实现
//滑动窗口问题
//使用双指针进行解题
class Solution {
public:
string minWindow(string s, string t) {
//定义双指针,初始化都为最左边
int left = 0;
int right = 0;
//定义最小的长度,初始化为无限大
int len = INT_MAX;
//存储最小窗口开始的地方,这样start~start+len就是窗口的字符串了
int start = 0;
//两个hash,用于存储匹配需求和匹配实际
unordered_map<char,int> needs;
unordered_map<char,int> window;
//初始化needs
for(int i=0;i<t.size();i++){
needs[t[i]]++;
}
//表示匹配情况,初始为都没有匹配
int match = 0;
while(right < s.size()){ //只要还在范围之内
//如果当前字符是needs集合里面的字符
if(needs.count(s[right])){
window[s[right]]++;
//如果满足了匹配条件
if(window[s[right]] == needs[s[right]]){
match++;
}
}
//如果match达到了相应的数量
while(match == needs.size()){
//那么接下来就是记录长度并且滑动我们的left指针
if(right - left + 1 < len ){ //如果长度小于当前最短长度,那么要进行更新
len = right - left + 1;
start = left;
}
//开始进行右移,如果这个字符是needs里面需要的话
if(needs.count(s[left])){
window[s[left]]--;
if(window[s[left]] < needs[s[left]]){
match--;
}
}
left++;
}
right++;
}
string res = ((len == INT_MAX) ? "":s.substr(start,len));
return res;
}
};
上面代码写错了!!!!!!!!!!!!!!!!!错在下面:
if(needs.count(s[left])){
window[s[left]]--;
if(window[s[left]] < needs[s[left]]){
match--;
}
}
代码实现
//滑动窗口问题
//使用双指针进行解题
class Solution {
public:
string minWindow(string s, string t) {
//定义双指针,初始化都为最左边
int left = 0;
int right = 0;
//定义最小的长度,初始化为无限大
int len = INT_MAX;
//存储最小窗口开始的地方,这样start~start+len就是窗口的字符串了
int start = 0;
//两个hash,用于存储匹配需求和匹配实际
unordered_map<char,int> needs;
unordered_map<char,int> window;
//初始化needs
for(int i=0;i<t.size();i++){
needs[t[i]]++;
}
//表示匹配情况,初始为都没有匹配
int match = 0;
while(right < s.size()){ //只要还在范围之内
//如果当前字符是needs集合里面的字符
if(needs.count(s[right])){
window[s[right]]++;
//如果满足了匹配条件
if(window[s[right]] == needs[s[right]]){
match++;
}
}
//如果match达到了相应的数量
while(match == needs.size()){
//那么接下来就是记录长度并且滑动我们的left指针
if(right - left + 1 < len ){ //如果长度小于当前最短长度,那么要进行更新
len = right - left + 1;
start = left;
}
//开始进行右移,如果这个字符是needs里面需要的话
if(needs.count(s[left])){
if(window[s[left]] == needs[s[left]]){
match--;
}
window[s[left]]--;
}
left++;
}
right++;
}
string res = ((len == INT_MAX) ? "":s.substr(start,len));
return res;
}
};
码后反思
- 在这道题目里面,滑动窗口
[left,right]
表示的是以s[left]
为首的字符串,能够满足匹配字符串t
中的所有字符的最短字符串是[left,right]
。这个定义读起来很抽象,但是如果结合滑动窗口的过程理解就不难了; - 使用滑动窗口,我们始终要明确下面三个方面的知识:
right
右移是寻找可行解的过程;left
右移是寻找最优解的过程;- 理解滑动窗口
[left,right]
表达的含义是什么?