ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【LeetCode-滑动窗口】最小覆盖子串

2020-05-23 21:52:55  阅读:281  来源: 互联网

标签:子串 字符 cnt right 窗口 curLen 滑动 LeetCode left


题目描述

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

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

说明:

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

题目链接: https://leetcode-cn.com/problems/minimum-window-substring/

思路

使用滑动窗口来做,使用两个指针 left 和 right 来标记窗口的大小,窗口大小为 right-left+1。left 和 right 初始化为 0,首先将 right 指向的元素加入窗口中并增加 right,直到窗口中包含 T 中所有元素,然后通过增加 left 来缩小窗口大小。算法具体过程如下:

我们使用一个哈希表cnt来记录 T 中元素出现的个数。那么,对于一个字符 c ,如果 c 在 T 中出现了,则 cnt[c]>0;如果 c 没有在 T 中出现,则 cnt[c]==0。使用 left 和 right 来遍历字符串 S,假设当前 right 指向的字符为 c ,将 cnt[c]--,如果 c 在 T 中出现,那么现在 cnt[c]>=0(之所以会大于 0 是因为 T 中可能会包含重复字符),否则 cnt[c]<0。如果减一后 cnt[c]>=0,说明我们在 S 中找到了一个在 T 中出现的字符,则当前找到的字符长度 curLen++。如果 curLen==T.length(),说明我们现在滑动窗口中已经包含了 T 中的所有字符,则可以通过增加 left 来缩小滑动窗口的大小。将 cnt[s[left]]++,如果 s[left] 是 T 中的字符,则加一后的 cnt[s[left]]>0,将 left+1 后,滑动窗口中就不完全包含 T 中的所有字符了(少了一个),这时停止缩小窗口的大小,也就是停止增大 left。如果加一后的 cnt[s[left]]<0,则说明 s[left] 没有在 T 中出现,可以继续缩小窗口。

循环结束的条件是 right>=S.length().

具体代码如下:

class Solution {
public:
    string minWindow(string s, string t) {
        unordered_map<char, int> cnt;
        for(auto c:t) cnt[c]++;  // 统计 t 中字符出现的次数

        int left=0, right=0;
        int minLen=INT_MAX;
        int curLen=0;  // 当前在s中已经找到的字符个数
        string ans="";
        while(right<s.length()){
            cnt[s[right]]--;
            if(cnt[s[right]]>=0) curLen++;

            while(curLen==t.length()){
                int windowSize=right-left+1; // 窗口大小
                if(windowSize<minLen){  // 找到了更短的符合要求的字符串
                    minLen=windowSize;
                    ans = s.substr(left, windowSize);
                }
                cnt[s[left]]++;
                if(cnt[s[left]]>0) curLen--; // 窗口中的字符不全
                left++;
            }
            right++;
        }
        return ans; 
    }
};
  • 时间复杂度:O(n)
    n 为 S 的长度。
  • 空间复杂度:O(n)

标签:子串,字符,cnt,right,窗口,curLen,滑动,LeetCode,left
来源: https://www.cnblogs.com/flix/p/12944630.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有