30.substring-with-concatenation-of-all-words

        说实在的,这道题还是比较难的,因为没有好的思路,其实从历年各个公司的算法真题来看,难题还是多出现在字符串上,这道题就是比较灵活的一道,没啥太好的思路,起初想着dfs,倒是可以做,但是开销蛮大的,因此,这里我参考大神的代码写了使用hash来解决问题。达到O(N)的时间复杂度和O(N)的空间复杂度。

         题目的大意是给定一个字符串和一个字符串对应的数组,在字符串中寻找一个字串,该字串正好包含字符串数组中所有的字符串,如果字符串数组中有重复,对应的字符子串中也应该有几个。举了例子,字符串数组中如果是:{"word", "word"},对应的字串也应该是"wordword"才可以。另外题目中还有一个重要的条件,字符串数组中每个字符串的长度是相等的,这对我们的后续工作很重要。返回符合条件的字符串的起始位置坐标。

         因为字符串数组中每一个字符串长度相等,假设长度为k,那么我们第一次就可以检测0~k-1,k~2k-1,……,第二次就可以检测1~k, k+1~2k, ……, …… ,第k次就可以检测k-1~2k-2,……,而每一次检测,对应的步长都是k,字符串总长度是N,两层循环,一层是k,另一层是N/k,所以,时间复杂度就是O(N).

         思路是这样的,因为要寻找的字符子串,也就要求我们寻找的目标串连续的,那整个寻找的过程类似于滑动窗口。如果能理解是滑动窗口了,那接下来我们要面对的是两种情况,

<1>,如果我们当前匹配的字符串发生失配的情况,那一定要从当前位置重新开始计数。

<2>,如果字符串出现某个单词个数比原数组中的多时,我们需要滑动窗口的左边界向右,将多余的单词之前的字符串都要舍弃。

以下是AC的代码:

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        vector<int> res;
        if (words.size()<1 || (s.size()<(words.size()*words[0].size()))) {
            return res;
        }
        int wordslen = words.size(), wordsize = words[0].size();
        unordered_map<string, int> unmap1;
        for (string str : words) {
            ++unmap1[str];
        }

        for (int i=0; i<wordsize; ++i) {
            unordered_map<string, int> unmap2;
            int left = i, count = 0;
            for (int j=i; j<=s.size()-wordsize; j+=wordsize) {
                if (unmap1.count(s.substr(j, wordsize))) {
                    ++unmap2[s.substr(j, wordsize)];
                    ++count;
                    while (unmap2[s.substr(j, wordsize)] > unmap1[s.substr(j, wordsize)]) {
                        --unmap2[s.substr(left, wordsize)];
                        left += wordsize;
                        --count;
                    }
                } else {
                    count = 0;
                    left = j+wordsize;
                    unmap2.clear();
                }
                
                if (count == wordslen) {
                    res.emplace_back(left);
                    --unmap2[s.substr(left, wordsize)];
                    left += wordsize;
                    --count;
                }
            }
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_29592167/article/details/83095326