题目描述:
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。即要求在源字符串s中找到长度最短的子串,这个子串包含目标字符串t中的所有字符,字符顺序没有要求。
示例:
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
说明:
如果 S 中不存这样的子串,则返回空字符串 “#”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
核心代码如下:
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
using namespace std;
string subStrOfMin(string a, string b) {
//定义一个vec,vec记录着当前滑动窗缺少b中哪几个字符,每个字符缺少多少个.
//对于字符ch,vec[ch]表示的是当前滑动窗缺少几个ch
//如果vec[ch]大于0,说明缺少vec[ch]个ch
//如果vec[ch]小于0,说明滑动窗中富余|map[ch]|个ch(vec[ch]的绝对值个)
//如果vec[ch]等于0,说明滑动窗中不缺少字符ch,也不富余字符ch
vector<int> vec(128, 0);
//初始化将目标字符串b中所有字符放到vec中,代表缺少t中所有的字符
for (int i = 0; i < b.size(); i++)
++vec[b[i]];
//for (auto ch : b)
//++vec[ch];
int length = b.size(); //设置计数器,记录当前滑动窗口缺少b中多少个字符
int begin = 0, end = 0, head = 0;
int len = 1000000;
while (end < a.size()) {
//当这个字符是滑动窗缺少的字符时,计数器减1
if (vec[a[end++]]-- > 0)
--length;
while (length == 0) {
if (end - begin < len) {
len = end - begin;
head = begin;
}
//当这个字符是滑动窗不缺也不富余的字符时,计数器加1
if (vec[a[begin++]]++ == 0)
++length;
}
}
if (len < 1000000)
return a.substr(head, len);
else
return "#";
//return len == 1000000 ? "#" : a.substr(head, len);
}
int main() {
string a, b;
cin >> a >> b;
cout << subStrOfMin(a, b) << endl;
return 0;
}
参考链接:https://blog.csdn.net/sinat_35261315/article/details/78730717