NC28 最小覆盖子串【牛客网】
文章目录
- 零、原题链接
- 一、题目描述
- 二、测试用例
- 三、解题思路
- 四、参考代码
零、原题链接
NC28 最小覆盖子串
一、题目描述
二、测试用例
三、解题思路
- 基本思路:
滑动窗口 + 散列表 - 具体思路:
- 先统计字符串 T 中的字符数量;
- 建立滑动窗口:
- 每次遍历字符,将该字符添加进窗口:
- 同时判断是否是属于字符串 T 中的字符,是则对应字符数量 – ,如果该字符数量将为 0 ,则字符类型数量 --;
- 如果字符类型数量为 0 ,则表示窗口已经包含了字符串 T 的所有字符,则开始收缩窗口:
- 每次收缩窗口,则判断舍弃的字符是否是字符串 T 中的字符,是则对应字符数量 ++ ,
- 如果该字符数量大于 0 ,则表示已经收缩到最小窗口,
- 则判断是否为当前最短的,是则更新最短字符串的起始坐标;
- 字符类型数量 ++ ;
- 每次遍历字符,将该字符添加进窗口:
- 判断最短字符串下标是否合法,合法则返回对应字符串,不合法说明不存在对应字符串,则返回空字符串;
四、参考代码
时间复杂度: O ( ∣ S ∣ + ∣ T ∣ ) \Omicron(|S|+|T|) O(∣S∣+∣T∣)【两个字符串都只遍历了一遍】
空间复杂度: O ( ∣ T ∣ ) \Omicron(|T|) O(∣T∣)【只需要额外存放字符串 T 的字符数量】
#include <unordered_map>
class Solution {public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param S string字符串* @param T string字符串* @return string字符串*/string minWindow(string S, string T) {unordered_map<char, int> m;for (int i = 0; i < T.length(); i++) {if (m.count(T[i]))m[T[i]]++;elsem.emplace(T[i], 1);}int minS = -S.length() - 1, minE = 0;int num = m.size();for (int s = 0, e = 0; e < S.length(); e++) {if (m.count(S[e]) && --m[S[e]] == 0)// 添加字符num--;while (num == 0) { // 舍弃字符if (m.count(S[s]) && ++m[S[s]] > 0) {if (e - s < minE - minS) {minS = s;minE = e;}num++;}s++;}}return minS < 0 ? "" : S.substr(minS, minE - minS + 1);}
};