140. Word Break II

Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. Return all such possible sentences.

Note:

  • The same word in the dictionary may be reused multiple times in the segmentation.
  • You may assume the dictionary does not contain duplicate words.

Example 1:

Input:

s = "
catsanddog
"
wordDict = 
["cat", "cats", "and", "sand", "dog"]
Output:

[
  "cats and dog",
  "cat sand dog"
]

Example 2:

Input:

s = "pineapplepenapple"
wordDict = ["apple", "pen", "applepen", "pine", "pineapple"]

Output:

[
  "pine apple pen apple",
  "pineapple pen apple",
  "pine applepen apple"
]

Explanation:
 Note that you are allowed to reuse a dictionary word.

Example 3:

Input:

s = "catsandog"
wordDict = ["cats", "dog", "sand", "and", "cat"]

Output:

[]

Solution

(1) Java

class Solution {
    public List<String> wordBreak(String s, List<String> wordDict) {
        List<String> rst = new ArrayList<>();
        Map<String, List<String>> cache = new HashMap<>();
        Set<String> wordSet = new HashSet<>();
        wordSet.addAll(wordDict);
        helper(s, wordSet, rst, new ArrayList<String>(), 0, cache);
        return rst;
    }

    private List<String> helper(String s, Set<String> wordSet, List<String> rst, List<String> list, int start, Map<String, List<String>> cache) {
        if (s.length() == start) {
            rst.add(String.join(" ",list));
            return new ArrayList<String>();
        }
        String tailStr = s.substring(start);
        if (cache.containsKey(tailStr)) { 
            List<String> l = cache.get(tailStr);
            for (String str : l) {
                rst.add(String.join(" ",list) + " " + str);
            }
            return l;
        }

        List<String> localRst = new ArrayList<>();
        for (int i = start+1; i <= s.length(); i++) {
            String sub = s.substring(start, i);
            if (wordSet.contains(sub)) {
                list.add(sub);
                List<String> l = helper(s, wordSet, rst, list, i, cache);
                list.remove(list.size()-1);
                if (i == s.length()) {
                    localRst.add(sub);
                } else {
                    for (String str : l) {
                        localRst.add(sub + " " + str);
                    }
                }                
            }
        }
        cache.put(s.substring(start), localRst);
        return localRst;
    }
}

(2) Python

class Solution:
    def wordBreak(self, s, wordDict):
        """
        :type s: str
        :type wordDict: List[str]
        :rtype: List[str]
        """
        def helper(start):
            if start == len(s):
                rst.append(" ".join(path))
                return []
            if s[start:] in mem:
                l = mem[s[start:]]
                for ll in l:
                    rst.append(" ".join(path)+" "+ll)
                return l
            path2 = []
            for i in range(start, len(s)):
                sub = s[start:i+1]
                if sub in wordSet:
                    path.append(sub)
                    ll = helper(i+1)
                    path.pop(len(path)-1)
                    if i == len(s)-1:
                        path2.append(sub)
                    else:
                        for pp in ll:
                            path2.append(sub+" "+pp)
            mem[s[start:]] = path2
            return path2


        if not s or not wordDict:
            return []
        mem = {}
        wordSet = set(wordDict)
        rst = []
        path = []
        helper(0)
        return rst

(3) Scala



results matching ""

    No results matching ""