【一天一道LeetCode】#76. Minimum Window Substring

原创 2016年06月01日 22:07:33

一天一道LeetCode

本系列文章已全部上传至我的github,地址:ZeeCoder‘s Github
欢迎大家关注我的新浪微博,我的新浪微博
欢迎转载,转载请注明出处

(一)题目

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

For example,
S = “ADOBECODEBANC”
T = “ABC”

Minimum window is “BANC”.

Note:
If there is no such window in S that covers all characters in T, return the empty string “”.

If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

(二)解题

题目大意:给定两个字符串S和T,求S中的包含T中所有字符的最小子串。

博主内心os:hard的题为什么每次都这么难做!

下面分享一下解题思路:

准备工作

遇到这种求子串的题目,不难想到要用到两个指针start和end记录子串在S中的开始和结束序号。
另外,本题还需要用到哈希的思想,故使用两个数组needFind[256]和find[256],前者用来记录我们需要找的字母及其出现次数,后来用来记录当前找到的字母及其出现次数。数组大小为256是因为字符ascii值在0~256之间。
那么,接下来,我们需要判断什么时候确定找到了一个子串包含T中的所有字符呢?
这里我们定义一个整形数count来记录“有效字符数”。那又有问题了,什么是有效字符?
假设T中有1个字符A,当我们找到第一个的时候count++,当我们找到第二个的时候超过了我们需要找的,故为无效字符,count不变。
又回到上一个问题,count等于T的长度的时候,就确定找到了一个子串包含T中的所有字符。

算法过程

做好如上的准备之后,就是整个算法的思想:
用[start,end]来标记窗口的起始位置,end一直向后扩张,并且find[]不停的记录已找到的字符及其出现的次数,count一直记录有效字符数。
当count等于字符串T的长度时,表示找到了符合要求的子串,这时,就需要对begin进行处理了。

  • 当S[begin]为不需要找的字符时,需要去除。如S=“CDAB”,T=“AB”,这时CD就需要去除
  • 当S[begin]需要找的字符,但超过了需要找的次数。如S=“AAB”,T=”AB”,这时A就需要去除

这样就找到了当前窗口下的最小子串,然后end继续向后扩张,重复如上步骤。
简而言之就是,扩张收缩在扩张在收缩……

具体的算法请看下面代码:

class Solution {
public:
    string minWindow(string s, string t) {
        int needFind[256] = {0};//记录需要找的字符及其出现次数
        int find[256] = {0};//记录找到的字符及其出现次数
        int count = 0;//记录有效字符数
        int begin=0,end=0;//记录当前窗口的起始位置和结束为止
        int minbegin = 0 , minlen = 2147483647;//记录最小窗口及其大小
        for(int i = 0 ; i < t.size() ; i++) needFind[t[i]]++;//初始化需要找的字符及其需要出现的次数
        for(;end<s.length();end++)
        {
            if(needFind[s[end]]==0) continue;//如果不是需要找的字符就继续下一个
            find[s[end]]++;//找到的需要找的字符,其次数加1
            if(find[s[end]]<=needFind[s[end]]) count++;.//如果找到的字符的次数小于或等于需要找的次数,则记为有效字符
            if(count==t.length())//找到了包含T中所有字符的子串
            {
                while(begin<end) {//去除窗口前面的无效字符
                    if(needFind[s[begin]]==0) begin++;//不需要找的字符去除
                    else if(find[s[begin]] > needFind[s[begin]])//超过次数的字符去除
                    {
                        find[s[begin]]--;//去除后次数减1
                        begin++;
                    }
                    else break;
                }
                int templen = end-begin+1;//计算当前窗口的长度
                if(minlen>templen)
                {
                    minlen = templen;
                    minbegin = begin;
                }
            }
        }
        return minlen == 2147483647 ?"":s.substr(minbegin,minlen);如果没有找到就返回“”,反之返回找到的子串
    }
};
版权声明:本文为博主原创文章,未经博主允许不得转载。

76. Minimum Window Substring(贪心,滑动窗口实现,hard)

Given a string S and a string T, find the minimum window in S which will contain all the characters ...
  • acm_1361677193
  • acm_1361677193
  • 2016年10月03日 20:06
  • 176

一天一道leetcode

Given a string s, partition s such that every substring of the partition is a palindrome. Return ...
  • qq_32782279
  • qq_32782279
  • 2017年08月08日 17:47
  • 61

LeetCode Longest Palindromic Substring 最长回文子字符串 两种方法分析解答

最难想的地方:P代表一个表,比较难想的就是P表的下标i和j代表原字符串中的两个前后下标s[i]和s[j]的位置。 如果P[i,j]为真,当且仅当si-1,si-2...sj-1,sj这一个子串都为pa...
  • kenden23
  • kenden23
  • 2013年11月23日 10:27
  • 2842

Minimum Window Substring 最小窗口覆盖所有字串

Minimum Window Substring Given a string S and a string T, find the minimum window in S whic...
  • u012605629
  • u012605629
  • 2015年09月28日 11:30
  • 335

【LeetCode-面试算法经典-Java实现】【005-Longest Palindromic Substring(最长回文子串)】

【005-Longest Palindromic Substring(最长回文子串)】给定一个字符串S,找出它的最大的回文子串,你可以假设字符串的最大长度是1000,而且存在唯一的最长回文子串。动态规...
  • DERRANTCM
  • DERRANTCM
  • 2015年07月17日 06:42
  • 2394

【一天一道LeetCode】#15 3Sum

一天一道LeetCode系列(一)题目 Given an array S of n integers, are there elements a, b, c in S such that a + ...
  • terence1212
  • terence1212
  • 2016年04月12日 11:40
  • 517

【LeetCode-面试算法经典-Java实现】【064-Minimum Path Sum(最小路径和)】

【064-Minimum Path Sum(最小路径和)】【LeetCode-面试算法经典-Java实现】【所有题目目录索引】原题  Given a m x n grid filled with no...
  • DERRANTCM
  • DERRANTCM
  • 2015年08月02日 06:05
  • 2293

【LeetCode-面试算法经典-Java实现】【120-Triangle(三角形)】

【120-Triangle(三角形)】【LeetCode-面试算法经典-Java实现】【所有题目目录索引】原题  Given a triangle, find the minimum path sum...
  • DERRANTCM
  • DERRANTCM
  • 2015年08月14日 06:13
  • 2374

[LeetCode] minimum window 包含所有字符的最小子字符串

包含所有字符的最小子字符串 smallest substring which contains all characters from a given string Suppose you are g...
  • jiyanfeng1
  • jiyanfeng1
  • 2014年09月22日 05:36
  • 627

每天一道C\C++笔试题V---内存泄露

俗语云:出来混,迟早是要还的。 下面是一道初级内存泄露题,程序员小懒儿显式的用new动态分配了内存,却忘记了用delete释放。 请找出问题的所在,代码如下: #include #incl...
  • lincyang
  • lincyang
  • 2013年03月07日 22:08
  • 3749
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【一天一道LeetCode】#76. Minimum Window Substring
举报原因:
原因补充:

(最多只允许输入30个字)