lintcode--最小子串覆盖

题目描述:
给定一个字符串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//初始化target的映射
        {
            hash_target[target[i]]++;
        }

        int begin,end;
        begin=0,end=0;

        int sublength=INT_MAX,low=0,high=0;
        while(endif(!judge_contain_target(hash,hash_target))//如果没有找到子串,就继续找
            {
                for(int i=0;iif(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;iif(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;iif(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]return false;
            }
        }
        return true;
    }
};

你可能感兴趣的:(lintcode)