LeetCode—76.最小覆盖子串[Minimum Window Substring]——分析及代码[C++]
一、题目
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。
示例:
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"
说明:
如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-window-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、分析及代码
1. 滑动窗口法(优化前)
(1)思路
滑动窗口法:用下标变量 l 和 r 记录当前子串的左右边界并进行滑动,常常只在需要时根据情况进行处理及记录。
先移动 r,直至窗口能够覆盖所需子串;再移动 l,直至窗口不能覆盖所需子串。
此时前一位置(因为 l 多移动了一次)的窗口即为本次最小窗口,根据目前记录的总最小窗口判断是否需要更新。
实现细节:
1)可用哈希表(unordered_map)分别记录字符串 t 及当前窗口中各个字符的出现次数,通过键值对在 O(1) 时间内修改;
2)可用一个整数 match 记录当前窗口与字符串 t 已匹配的字符数量,仅当其中各字符第一次达到 t 中字符对应个数时 match++,通过判断 match 与 t 中无重复字符数量是否相等,判断窗口是否已覆盖字符串;
3)每次移动完窗口左边界后再判断窗口大小即可;
4)通过窗口长度是否修改判断是否存在符合条件的子串。
(2)代码
class Solution {
public:
string minWindow(string s, string t) {
int ssize = s.size(), tsize = t.size();
if (tsize == 0 || ssize < tsize)
return "";
unordered_map<char, int> w;//windows
unordered_map<char, int> n;//need
int l = 0, r = 0;
int match