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"barfoothefoobarman"
words["foo", "bar"]
You should return the indices: [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

Popular posts from this blog

How Django Works (4) URL Resolution

Python Class Method and Class Only Method

How Django works (3): Testing Server and Static Files Serving