LeetCode 30 Substring with Concatenation of All Words (C++, Python)
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 wordsexactly once and without any intervening characters.
For example, given:
s:
words:
s:
"barfoothefoobarman"
words:
["foo", "bar"]
You should return the indices:
(order does not matter).
[0,9]
.(order does not matter).
Solution C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | class Solution { public: vector<int> findSubstring(string s, vector<string>& words) { int len = words[0].length(); vector<int> ret; if (s.length() < len * words.size()) return ret; sort(words.begin(), words.end()); unordered_map<string, int> mapwords; int totalwords = 0; for (string& word: words) { ++ mapwords[word]; ++ totalwords; } unordered_map<string, int>mapwords2; for (int i = 0; i < len; ++i) { int matched = 0; int start = -1; mapwords2.clear(); for (int j = i; j <= s.length() - len; j += len) { string tmp = s.substr(j, len); if (mapwords.find(tmp) == mapwords.end()) { start = -1; } else { ++ mapwords2[tmp]; if (mapwords2[tmp] > mapwords[tmp]) { int lj = start; while (s.substr(lj, len) != tmp) { -- mapwords2[s.substr(lj, len)]; lj += len; -- matched; } -- mapwords2[tmp]; start = lj + len; } else { if (start == -1) { start = j; } ++ matched; if (matched == totalwords) { ret.push_back(start); -- matched; -- mapwords2[s.substr(start, len)]; start += len; } } } if ((start == -1) && (matched != 0)) { mapwords2.clear(); matched = 0; } } } return ret; } }; |
Solution Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | class Solution: # @param {string} s # @param {string[]} words # @return {integer[]} def findSubstring(self, s, words): ret = [] wordnum = len(words) if not wordnum: return ret wordlen = len(words[0]) if not wordlen: return ret strlen = len(s) if strlen < wordnum * wordlen: return ret wordstat = {} for word in words: try: wordstat[word] += 1 except KeyError: wordstat[word] = 1 wordstat2 = {} for i in range(wordlen): start = -1 wordstat2.clear() for j in range(i, strlen - wordlen + 1, wordlen): curstr = s[j: j + wordlen] if curstr in wordstat: try: wordstat2[curstr] += 1 except KeyError: wordstat2[curstr] = 1 if wordstat2[curstr] > wordstat[curstr]: while s[start: start + wordlen] != curstr: wordstat2[s[start: start + wordlen]] -= 1 start += wordlen wordstat2[s[start: start + wordlen]] -= 1 start += wordlen else: if start == -1: start = j if sum(wordstat2.itervalues()) == wordnum: ret.append(start) wordstat2[s[start: start + wordlen]] -= 1 start += wordlen else: start = -1 if start == -1 and wordstat2: wordstat2.clear() matched = 0 return ret |