30. Substring with Concatenation of All Words找出串联所有词的子串

题目:https://leetcode.com/problems/substring-with-concatenation-of-all-words/description/

You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.

For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).

找到索引,连续能匹配所有子串,(各子串匹配的顺序不考虑);

比如要匹配的子串集["foo", "bar"],那么母串是"barfoothefoobarman"时,返回[0,9]。因为index = 0时有“barfoo”,index = 9时,有“foobar

解决:

1、用到map结构(有点像hash)的counts,用来存放要匹配的子串s还有要匹配它的次数:counts( s ) = 要匹配的次数。

  比如counts("bar") = 1,counts("foo") = 1;

2、从母串的第一位开始匹配(匹配成功或失败,第二次都从第二位开始,第三次从第三位。。即每次向后挪一位进行匹配):{

    取长度len(每个word的长度)的字符串word{

      看这个word是否在要匹配的counts中包含?

      如果包含,进行seen(word)++,并判断seen(word)是否大于counts(word)。

      如果不包含或子串出现次数大于要匹配的次数,break;

    }接着紧挨着再取长度为len。。

  }

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        unordered_map<string, int> counts;  //string代表子串,int代表要匹配的word的个数
        for (string word : words)
            counts[word]++; //某个word要匹配的个数
        int n = s.length(), num = words.size(), len = words[0].length(); //n:母串长度,num:要匹配几个word,len:字串长度(每个word的长度相等)
        vector<int> indexes;   //放入匹配的index
        for (int i = 0; i < n - num * len + 1; i++) {  //从母串的第一个元素开始,每次挪一位匹配
            unordered_map<string, int> seen;     //seen记录word被包含的次数(不得大于要匹配的次数:counts中记录)
            int j = 0;
            for (; j < num; j++) {(
                string word = s.substr(i + j * len, len);   //每次从母串截取长度len长度的字符串word,看是否是要匹配的word
                if (counts.find(word) != counts.end()) {  //word是否在counts中找到
                    seen[word]++;  //
                    if (seen[word] > counts[word])  //匹配多余时要break(比如只要匹配一个abb,但是总共出现了两个abb就不对了)
                        break;
                } 
                else break;
            }
            if (j == num) indexes.push_back(i);  //每个word都匹配好,
        }
        return indexes;
    }
};

最笨的方法了。其他好方法可参见:https://leetcode.com/problems/substring-with-concatenation-of-all-words/discuss/

原文地址:https://www.cnblogs.com/hozhangel/p/7840619.html