lintcode--最小子串覆盖

来源:互联网 发布:php调用父类构造函数 编辑:程序博客网 时间:2024/05/19 16:37

题目描述:
给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串。

注意事项:
如果在source中没有这样的子串,返回”“,如果有多个这样的子串,返回起始位置最小的子串。

说明:
在答案的子串中的字母在目标字符串中是否需要具有相同的顺序?
——不需要。

样例:
给出source = “ADOBECODEBANC”,target = “ABC” 满足要求的解 “BANC”

思路讲解:
我们首先将目标字符串映射到一个大小为128的hash_target数组,然后我们建立一个同样的hash数组,然后遍历source这个字符串,并用两个指针begin和end,每次都将字符与target的没以恶搞字符比较,然后将其在hash中对应的位置加一,并将其与hash_target比较,如果是,则说明找到一个子串可以包含target的,然后我们将从begin开始,逐个删除字符(这一步是为了得到最小的子串包含target的),如果删除之后,hash还是比hash_target大,说明找到了一个较小的子串;如果没有就从end开始继续遍历source,这样就可以得到了最小的子串。
举个栗子:
ADOBECODEBANC
a.当begin=0时,hash为空,显然不满足子串,则将end后移直至end=5时。此时hash的计数为A=1,B=1,C=1,满足子串要求,此时最小子串为ADOBEC,长度为6。最后将A的计数减1,此时hash的计数为A=0,B=1,C=1。
b.当begin=1时,由于hash不满足子串要求,则继续步骤a直至end=10。此时hash的计数为A=1,B=2,C=1,最小子串为DOBECODEBA,长度为10。然后将D去掉,此时hash的计数为A=1,B=2,C=1。
c.当begin=2时,最小子串为OBECODEBA,直至begin=6时,hash的计数为A=1,B=2,C=0,将end继续向后移动至最后一位,hash重新满足子串要求。再继续重复上述步骤可获取最小子串。

代码详解:

class Solution {public:    /*     * @param source : A string     * @param target: A string     * @return: A string denote the minimum window, return "" if there is no such a string     */    string minWindow(string &source , string &target) {        // write your code here        int length=target.length();        if(source=="")        return "";        vector<int> hash(128,0);        vector<int> hash_target(128,0);        for(int i=0;i<length;i++)//初始化target的映射        {            hash_target[target[i]]++;        }        int begin,end;        begin=0,end=0;        int sublength=INT_MAX,low=0,high=0;        while(end<source.length())        {            if(!judge_contain_target(hash,hash_target))//如果没有找到子串,就继续找            {                for(int i=0;i<length;i++)                {                    if(target[i]==source[end]){                        hash[target[i]]++;                        break;                    }                }                end++;            }            if(judge_contain_target(hash,hash_target)){//如果找到子串,就看是否存在较短的子串                if(sublength>(end-begin)){                    sublength=end-begin;                    low=begin;                    high=end;                }                for(int i=0;i<length;i++)                {                    if(target[i]==source[begin]){                        hash[target[i]]--;                        break;                    }                }                begin++;            }        }        while(judge_contain_target(hash,hash_target))//特殊情况的处理例如:aaaaaaaabcd和abcd        {           if(sublength>(end-begin)){                    sublength=end-begin;                    low=begin;                    high=end;                }                for(int i=0;i<length;i++)                {                    if(target[i]==source[begin]){                        hash[target[i]]--;                        break;                    }                }                begin++;         }        if(sublength==INT_MAX){            return "";        }        else{            return source.substr(low,sublength);        }    }    bool judge_contain_target(vector<int>hash,vector<int>hash_target)//判断是否找到了子串    {        for(int i=0;i<128;i++)        {            if(hash[i]<hash_target[i]){                return false;            }        }        return true;    }};
原创粉丝点击