【LeetCode】76. 最小覆盖子串(典型滑动窗口)

题目链接

https://leetcode-cn.com/problems/minimum-window-substring/

题目描述

给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。

示例:
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"

说明:
如果 S 中不存这样的子串,则返回空字符串 ""。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

解题思路

1.暴力枚举

双重for循环,从字符串S的每一个字符开始枚举,直到找到满足字符串T的子串,利用ans变量记录子串长度并进行迭代更新。

2.滑动窗口

标准的滑动窗口:

1.把[left,right]称为一个窗口;
2.先右移右指针扩大窗口,直到窗口中的数字满足字符串T数组要求;
3.满足要求时,停止增加right,转而增加left缩小窗口,直到不满足要求.
4.重复2,3步直到right走到字符串S的尽头。

滑动窗口的模板:

int left = 0, right = 0; //left right为双指针

while (right < s.size())

{

    window.add(s[right]);

    right++; //右移右指针扩大窗口

    while (valid) //直到窗口中的字符串满足字符串T的要求;

    {

        window.remove(s[left]); //满足要求时,停止增加right,转而增加left缩小窗口,直到不满足要求

        left++;

    }

}

这题对于我来说,难点在与valid条件的判断,采用

if(window[s[r]] == mp[s[r]]) count++;
if(count == mp.size())

能够解决以下实例产生的问题:

S = "BBBBCEAW"  T = "ABC"

S = "bbaa"  T = "aba"

AC代码

 1 class Solution {
 2 public:
 3     string minWindow(string s, string t) {
 4         if(t.size() > s.size()) return "";
 5         if(s == t) return t;
 6         map<char,int> mp;
 7         for(int i = 0; i < t.size(); i++) mp[t[i]]++;
 8         int l = 0;
 9         int r = 0;
10         int count = 0;
11         int len = INT_MAX;
12         int start = -1;
13         map<char,int>window;
14         while(l <= r && r < s.size())
15         {
16             if(mp.count(s[r]) == 1)
17             {
18                 window[s[r]]++;
19                 if(window[s[r]] == mp[s[r]]) count++;
20             }
21         
22             if(count == mp.size()) //19行与22行代码就是对于valid条件的判断。
23             {
24                 while(l < r)
25                 {
26                     if(window.count(s[l]) == 0) l++;
27                     else if(window[s[l]] == mp[s[l]]) break;
28                     else if(window[s[l]] > mp[s[l]])
29                     {
30                         window[s[l]]--;
31                         l++;
32                     }
33                 }
34                 if(r-l+1 < len)
35                 {
36                     len = r-l+1;
37                     start = l;
38                 }
39             }
40             r++;
41         }
42         if(start != -1) return s.substr(start,len);
43         else return "";
44     }
45 };

 

posted @ 2020-05-24 22:15  控球强迫症  阅读(243)  评论(0编辑  收藏  举报