来自LEETCODE 76.
大意:给一个S字符串和一串T,问你S的最短的哪一部分包括了T的所有字母元素。
如:输入:s = “ADOBECODEBANC”, t = “ABC”
输出:“BANC”
用划窗:思路,先固定左边,向右扩展,扩展到满足条件为止(继续往右扩展木有意义了)。随后固定住右边,看看尝试往左移动的话,会不会继续满足条件,直到不满足条件为止。 不满足后,重复上述步骤,先固定左边,看看右边能否满足条件,以此类推。
class Solution {
public:
string minWindow(string s, string t) {
vector<int> need(128, 0); //某个字母的需求,这里用128是因为这个区间的编码可以完全覆盖大小写字母
vector<bool> flag(128, false); //某个字母是否在T字符串中
for (int i = 0; i < t.size(); i++)
{
need[t[i]]++;
flag[t[i]] = true;
}
//当前s内拥有的t元素 ,左指针 , 最小长度 ,最小长度的左指针
int cnt = 0, l = 0, MIN = s.size() + 1, min_l = 0;
for (int r = 0; r < s.size(); r++)
{
if (flag[s[r]]) //如果当前右指针是t中元素
{
need[s[r]]--; //需求量减少1
if(need[s[r]] >= 0)
cnt++; //如果该元素还有需求,拥有的元素个数加一
}
while (cnt == t.size()) //当前l - r的片段已经包含了所有的t元素
{
if (r - l + 1 < MIN)
{
min_l = l;
MIN = r - l + 1; //更新最优情况数据
}
if (flag[s[l]] && ++need[s[l]] > 0) //如果是t中元素,且加一之后需求不够了
--cnt; //改变循环条件
l++; //讨论过了l在此处的片段窗口最小,于是移动左指针,开始往前找
}
}
return MIN > s.size() ? "" : s.substr(min_l, MIN); //substr(起始截点,截多少个) 这里好容易记错
}
};
本文总结了如何使用双指针算法解决LEETCODE 76题,即寻找字符串S中最短的子串,该子串包含另一个字符串T的所有字符。通过固定左侧指针并扩展右侧指针直至满足条件,然后固定右侧指针并向左移动尝试保持条件,不断迭代寻找最短子串。
967

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



