给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
注意:
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
示例 2:
输入:s = "a", t = "a"
输出:"a"
示例 3:
输入: s = "a", t = "aa"
输出: ""
解释: t 中两个字符 'a' 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。
提示:
1 <= s.length, t.length <= 105
s 和 t 由英文字母组成
思路:相当于在str2字符串中找一个包含str1的字符子串并输出(只要包含就行,不考虑顺序)
用o(n)的时间来解决这道题,因此我们考虑用哈希数组来记录str1字符串中每个字符出现的次数,只要str2中的一个子字符串中的字符和有str1中的字符且出现次数一样 就将找个子字符串输出来
难点:怎么缩小区间
当hash_str2[str2[j]] > hash_str1[str2[j]],我们说某个数的字符出现次数太多了 我们可以将其删去,缩小区间
#include<iostream>
#include<unordered_map>
#include<string>
using namespace std;
int main() {
int cnt=0;
int minstr = 0x3f3f3f3f;
unordered_map<char, int>hash_str1;
unordered_map<char, int>hash_str2;
string str1;
string str2;
string ans;
cin >> str2;//大的字符串
cin >> str1;//小的字符串
for (int i = 0; i < str1.size(); i++) {
hash_str1[str1[i]]++;//将字串中的字符出现的次数统计在哈希数组中
}
for (int i = 0, j = 0; i < str2.size(); i++) {
if (hash_str2[str2[i]] < hash_str1[str2[i]]) {
cnt++;
}
hash_str2[str2[i]]++;
//怎样实现统计str2中的str1 ,如果够了则不在移动i,移动j。
while (hash_str2[str2[j]] > hash_str1[str2[j]]) {//让左指针j向右移直到右移到是最小的覆盖字串为止
hash_str2[str2[j]]--;
j++;
}
if (cnt == str1.size()) {
if ( i - j + 1 < minstr) {//筛选最小字串
minstr = i - j + 1;
ans = str2.substr(j, i - j + 1);
cout << "ans:" << ans << endl;
}
}
}
return 0;
}

764

被折叠的 条评论
为什么被折叠?



