- 链接 : 最小覆盖子串
- 题意:给定一个字符串s以及t,判断 s 里包含 t 所有字母的最小子串。
- 思路:双指针的应用——滑动窗口
(官方题解)举个例子,S = “ABAACBAB”,T = “ABC”
首先两个指针 left = right = 0
然后right 逐渐增加,直到窗口包含t 所有字母
这时,维护最小的窗口,所以逐渐 缩减窗口,left ++ 。如果窗口减小后,不满足条件,则right++。
- 代码:
注释我写的很详细
class Solution {
public:
string minWindow(string s, string t) {
//need是 t包含的字母, window是滑动窗口
unordered_map<char,int> need, window;
for(char c : t) need[c] ++;
//left,right是窗口
//valid 是判断满足条件与否,window内每有一个t内的字母,valid++
int left = 0, right = 0, valid = 0;
int start = 0, len = INT_MAX;
while(right < s.size()){
//每次窗口滑动
char tmp = s[right];
right ++;
//t中所有tmp,window内都有,则valid++
if(need.count(tmp)){
window[tmp] ++;
if(window[tmp] == need[tmp]){
valid ++;
}
}
//窗口内包含t内所有字母
while(valid == need.size()){
//每次更新最小窗口。start和len是确定最后子串的。
//left和right最后不一定是最小窗口
if(right - left < len){
start = left;
len = right - left;
}
//满足条件后窗口缩减
char d = s[left];
left ++;
//缩减后丢失的字母在t中出现,且丢失后不满足条件。
if(need.count(d)){
if(window[d] == need[d]){
valid --;
}
window[d] --;
}
}
}
return len == INT_MAX ? "" : s.substr(start,len);
}
};
-
遇到的问题:
1、今天另外一道题所学到的知识:
vector< int > a(n) 。 用此种方法构造vector的长度,这样可以直接 cin>>a[i]2、文件流输入输出
#define _DEBUG
#ifdef _DEBUG
freopen(“in.txt”,“r”,stdin);
freopen(“out.txt”,“w”,stdout);
#endif此结构是 #ifdef 标识符 ***** #endif
如果define了标识符,那么里面的部分就会编译运行,否则不会。
如上, #define _DEBUG,则freopen两行可以编译运行。提交的时候只需要注释掉宏定义的此句即可。3、INT_MAX 是头文件 limit.h 里的宏定义
因为用INF的时候,以前都是用 0x7fffffff,就是int的最大值,除了符号位是0,其他都是1。
INT_MAX等于此值,可以直接使用。4、unordered_map
是无序的一个键值对集合。
map有个特性,即插入后自动按照 key的值进行排序,所以是有序的。性能上应该不如 unordered_map
声明: unordered_map<char, int> mp;
主要方法基本和map一致。