Problem: 76. 最小覆盖子串
文章目录
- 题目描述
- 思路
- 复杂度
- Code
题目描述
思路
1.定义两个map集合need和window(以字符作为键,对应字符出现的个数作为值),将子串t存入need中;
2.定义左右指针left、right均指向0(形成窗口),定义int类型变量len记录最小窗口长度,valid记录当前窗口否存最短子串中的字符个数;
3.向右扩大窗口,遍历到到的字符c如果在need中时,window[c]++,同时如果window[c] == need[c],则valid++;
4.如果valid == need.size(),则表示可以开始收缩窗口,并更新最小窗口禅读(如果移除的字符在need中,同时window[d] == need[d],则valid–,window[d]–);
复杂度
时间复杂度:
O ( n ) O(n) O(n);其中 n n n为字符串 s s s的长度
空间复杂度:
O ( n ) O(n) O(n)
Code
class Solution {
public:
/**
* Two pointer
*
* @param s Given string
* @param t Given string
* @return string
*/
string minWindow(string s, string t) {
unordered_map<char, int> need;
unordered_map<char, int> window;
for (char c: t) {
need[c]++;
}
int left = 0;
int right = 0;
int valid = 0;
// Records the starting index and length of the minimum overlay substring
int start = 0;
int len = INT_MAX;
while (right < s.size()) {
//c is the character moved into the window
char c = s[right];
// Move the window right
right++;
// Perform some column updates to the data in the window
if (need.count(c)) {
window[c]++;
if (window[c] == need[c]) {
valid++;
}
}
// Determine whether to shrink the left window
while (valid == need.size()) {
// Update the minimum overlay substring
if (right - left < len) {
start = left;
len = right - left;
}
//d is the character to be moved out of the window
char d = s[left];
// Move the window left
left++;
// Perform some column updates to the data in the window
if (need.count(d)) {
if (window[d] == need[d]) {
valid--;
}
window[d]--;
}
}
}
// Returns the minimum overlay substring
return len == INT_MAX ? "" : s.substr(start, len);
}
};