140. Word Break II 单词拆分 II
作者: 负雪明烛 id: fuxuemingzhu 个人博客: https://fuxuemingzhu.cn/
题目地址:https://leetcode.com/problems/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:[]给了一个字典,问给定的字符串s能有多少种被字典构造出来的方式,返回每一种构造方式。
这个题就是139. Word Break的变形,现在要求所有的构造方式了。
一般这种题就需要使用递归,把所有的构造方式都求出来。这个题必须使用字典保存已经能切分的方式,否则,递归的时间复杂度太高。我们定义函数dfs,其含义是字符串s能被字典中的元素构成的所有构造方式字符串(中间由空格分割)。所以,我们只需要知道如果当前的字符串能分割,再拼接上后面的分割就行了。如果后面部分不能分割,应该返回的是空的vector,这样就不会产生新的结果字符串放入到res里。
Python代码如下:
class Solution(object): def wordBreak(self, s, wordDict): """ :type s: str :type wordDict: List[str] :rtype: List[str] """ res = [] memo = dict() return self.dfs(s, res, wordDict, memo)
def dfs(self, s, res, wordDict, memo): if s in memo: return memo[s] if not s: return [""] res = [] for word in wordDict: if s[:len(word)] != word: continue for r in self.dfs(s[len(word):], res, wordDict, memo): res.append(word + ("" if not r else " " + r)) memo[s] = res return resC++代码如下:
class Solution {public: vector<string> wordBreak(string s, vector<string>& wordDict) { set<string> wordset(wordDict.begin(), wordDict.end()); unordered_map<string, vector<string>> m; return dfs(wordset, s, m); }private: vector<string> dfs(set<string>& wordset, string s, unordered_map<string, vector<string>>& m) { if (m.count(s)) return m[s]; if (s.empty()) return {""}; vector<string> res; for (string word : wordset) { if (s.substr(0, word.size()) != word) continue; vector<string> remain = dfs(wordset, s.substr(word.size()), m); for (string r : remain) { res.push_back(word + (r.empty() ? "" : " ") + r); } } return m[s] = res; }};也可以不用一个新的函数,直接在原始的函数上进行操作。这时候就需要一个全局的字典。代码如下:
class Solution {public: vector<string> wordBreak(string s, vector<string>& wordDict) { if (m.count(s)) return m[s]; if (s.empty()) return {""}; vector<string> res; for (string word : wordDict) { if (s.substr(0, word.size()) != word) continue; for (string r : wordBreak(s.substr(word.size()), wordDict)) { res.push_back(word + (r.empty() ? "" : " ") + r); } } return m[s] = res; }private: unordered_map<string, vector<string>> m;};参考资料:http://www.cnblogs.com/grandyang/p/4576240.html
2018 年 12 月 19 日 —— 感冒了,好难受

评论与交流