LeetCode 140 Word Break II (C++, Python)

Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.
Return all such possible sentences.
For example, given
s = "catsanddog",
dict = ["cat", "cats", "and", "sand", "dog"].
A solution is ["cats and dog", "cat sand dog"].

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
class Solution {
    bool intWordBreak(const unordered_multimap<int,int>& words, vector<bool>& dp,
               int start, const string& s, vector<pair<int,int>>& stack, vector<string>& ret) {
        if (start == s.length()) {
            string tmp;
            for (auto p: stack) {
                if (tmp.empty()) {
                    tmp += s.substr(p.first, p.second - p.first + 1);
                } else {
                    tmp += ' ';
                    tmp += s.substr(p.first, p.second - p.first + 1);
                }
            }
            ret.push_back(move(tmp));
            return true;
        }
        if (!dp[start]) return false; 
        bool success = false;
        auto itpair = words.equal_range(start);
        for (auto it = itpair.first; it != itpair.second; ++it) {
            stack.push_back(*it);
            success |= intWordBreak(words, dp, it->second + 1, s, stack, ret);
            stack.pop_back();
        }
        if (!success) {
            dp[start] = false;
        }
        return success;
    }

public:
    vector<string> wordBreak(string s, unordered_set<string> &dict) {
        vector<bool> dp(s.length(), true);
        unordered_multimap<int, int> words;
        for (int i = 0; i < s.length(); ++i) {
            for (int j = i; j < s.length(); ++j) {
                if (dict.find(s.substr(i, j - i + 1)) == dict.end()) continue;
                words.insert({i, j});
            }
        }
        vector<string> ret;
        vector<pair<int, int>> stack;
        intWordBreak(words, dp, 0, s, stack, ret);
        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
class Solution:
    def intWordBreak(self, memo, start, s, dict, stack, ret):
        if start == len(s):
            ret.append(' '.join(stack))
            return True
        if not memo[start]: return False
        success = False
        for j in range(start, len(s)):
            if s[start:j + 1] not in dict: continue
            stack.append(s[start:j + 1])
            success |= self.intWordBreak(memo, j + 1, s, dict, stack, ret)
            stack.pop()
        if not success:
            memo[start] = False
        return success
    # @param s, a string
    # @param dict, a set of string
    # @return a list of strings
    def wordBreak(self, s, dict):
        ret = []
        stack = []
        memo = [True] * len(s)
        self.intWordBreak(memo, 0, s, dict, stack, ret)
        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