Leetcode: Substring with Concatenation of All Words

来源:互联网 发布:阿里云机房测速 编辑:程序博客网 时间:2024/05/01 00:13

        题目链接:Substring with Concatenation of All Words

        这道题容易想到的是暴力算法,不过一开始就被我否定了,觉得应该不能AC,后来看到网上纯暴力的也能AC,好吧QAQ...

        相比暴力算法,可以下列优化措施:

        (1)L中的字符串可以看作是固定长度的单个“字符”, 这些字符必须是连续出现,且L中的每个字符都要出现一次,不管重复与否。因此我们可以采用移动窗口的思路。左右边界分别记为Wl,Wr,指针Pt移动的单位长度是L中单个字符串的长度。

                i:如果指针所指字符属于L,且该字符重复出现的次数不超过L中重复次数,则Wr = Wr+1;

                ii:如果指针所指字符属于L,但是该字符出现的次数已经达到上限,假设从Wl开始,遍历第一次出现该字符的位置为pos,遍历过程中,遇到其他字符,则在维护字符出

                   现次数的map中,相应字符出现次数减一,更改Wl = pos + 1, Wr = Wr + 1;

                iii:如果指针所指字符不属于L,则Wl = Pt + 1, Wr = Wl

         (2)如上所述,发现每次指针的移动单位是L中单个字符串长度,因此在最开始的Wl位置应该设为:0~~(单位长度-1),这样才不会出现遗漏的情况

         下面贴出AC代码,时间复杂度O(S.length() ):

class Solution{protected:vector<int> vi;unordered_map<string, int> msb;int Slen, Llen, Lsize;protected:void Test(string &S, vector<string> &L, int start){unordered_map<string, int> msi;int k = 0, l = 0, len = 0;string str;for (k = start; k < Slen && start <= Slen - Llen*Lsize; k += Llen){str = S.substr(k, Llen);if (msb.find(str) == msb.end()){start = k + Llen;len = 0;msi.clear();}else if (msi[str] == msb[str]){for (l = start; str != S.substr(l, Llen); l += Llen){--msi[S.substr(l, Llen)];--len;}start = l + Llen;}else{++msi[str];++len;}if (len == Lsize){vi.push_back(start);k = start;start += Llen;len = 0;msi.clear();}}}public:vector<int> findSubstring(string &S, vector<string> &L){Slen = S.length(), Llen = L[0].length(), Lsize = L.size();for (int i = 0; i < Lsize; ++i)++msb[L[i]];for (int st = 0; st < Llen; ++st)Test(S, L, st);return vi;}};


0 0
原创粉丝点击