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:
[]

139. Word Break 的拓展,那道题只是让判断是否可以拆分,而这道题要求输出所有可能的拆分组合。

解法:dp + dfs,先用dp计算是否可以拆分,然后用dfs求出具体拆分的组合。

Java:

public static List<String> wordBreak(String s, Set<String> dict) {
//create an array of ArrayList<String>
List<String> dp[] = new ArrayList[s.length()+1];
dp[0] = new ArrayList<String>(); for(int i=0; i<s.length(); i++){
if( dp[i] == null )
continue; for(String word:dict){
int len = word.length();
int end = i+len;
if(end > s.length())
continue; if(s.substring(i,end).equals(word)){
if(dp[end] == null){
dp[end] = new ArrayList<String>();
}
dp[end].add(word);
}
}
} List<String> result = new LinkedList<String>();
if(dp[s.length()] == null)
return result; ArrayList<String> temp = new ArrayList<String>();
dfs(dp, s.length(), result, temp); return result;
} public static void dfs(List<String> dp[],int end,List<String> result, ArrayList<String> tmp){
if(end <= 0){
String path = tmp.get(tmp.size()-1);
for(int i=tmp.size()-2; i>=0; i--){
path += " " + tmp.get(i) ;
} result.add(path);
return;
} for(String str : dp[end]){
tmp.add(str);
dfs(dp, end-str.length(), result, tmp);
tmp.remove(tmp.size()-1);
}
}

Java:

public List<String> wordBreak(String s, Set<String> wordDict) {
ArrayList<String> [] pos = new ArrayList[s.length()+1];
pos[0]=new ArrayList<String>(); for(int i=0; i<s.length(); i++){
if(pos[i]!=null){
for(int j=i+1; j<=s.length(); j++){
String sub = s.substring(i,j);
if(wordDict.contains(sub)){
if(pos[j]==null){
ArrayList<String> list = new ArrayList<String>();
list.add(sub);
pos[j]=list;
}else{
pos[j].add(sub);
} }
}
}
} if(pos[s.length()]==null){
return new ArrayList<String>();
}else{
ArrayList<String> result = new ArrayList<String>();
dfs(pos, result, "", s.length());
return result;
}
} public void dfs(ArrayList<String> [] pos, ArrayList<String> result, String curr, int i){
if(i==0){
result.add(curr.trim());
return;
} for(String s: pos[i]){
String combined = s + " "+ curr;
dfs(pos, result, combined, i-s.length());
}
} 

Java:

public class Solution {
Map<String, List<String>> done = new HashMap<>();
Set<String> dict; public List<String> wordBreak(String s, Set<String> dict) {
this.dict = dict;
done.put("", new ArrayList<>());
done.get("").add(""); return dfs(s);
} List<String> dfs(String s) {
if (done.containsKey(s)) {
return done.get(s);
}
List<String> ans = new ArrayList<>(); for (int len = 1; len <= s.length(); len++) {
String s1 = s.substring(0, len);
String s2 = s.substring(len); if (dict.contains(s1)) {
List<String> s2_res = dfs(s2);
for (String item : s2_res) {
if (item == "") {
ans.add(s1);
} else {
ans.add(s1 + " " + item);
}
}
}
}
done.put(s, ans);
return ans;
}
} 

Python:

class Solution(object):
def wordBreak(self, s, wordDict):
"""
:type s: str
:type wordDict: Set[str]
:rtype: List[str]
"""
n = len(s) max_len = 0
for string in wordDict:
max_len = max(max_len, len(string)) can_break = [False for _ in xrange(n + 1)]
valid = [[False] * n for _ in xrange(n)]
can_break[0] = True
for i in xrange(1, n + 1):
for l in xrange(1, min(i, max_len) + 1):
if can_break[i-l] and s[i-l:i] in wordDict:
valid[i-l][i-1] = True
can_break[i] = True result = []
if can_break[-1]:
self.wordBreakHelper(s, valid, 0, [], result)
return result def wordBreakHelper(self, s, valid, start, path, result):
if start == len(s):
result.append(" ".join(path))
return
for i in xrange(start, len(s)):
if valid[start][i]:
path += [s[start:i+1]]
self.wordBreakHelper(s, valid, i + 1, path, result)
path.pop() 

C++:

class Solution {
public:
vector<string> wordBreak(string s, unordered_set<string>& wordDict) {
vector<string> res;
string out;
vector<bool> possible(s.size() + 1, true);
wordBreakDFS(s, wordDict, 0, possible, out, res);
return res;
}
void wordBreakDFS(string &s, unordered_set<string> &wordDict, int start, vector<bool> &possible, string &out, vector<string> &res) {
if (start == s.size()) {
res.push_back(out.substr(0, out.size() - 1));
return;
}
for (int i = start; i < s.size(); ++i) {
string word = s.substr(start, i - start + 1);
if (wordDict.find(word) != wordDict.end() && possible[i + 1]) {
out.append(word).append(" ");
int oldSize = res.size();
wordBreakDFS(s, wordDict, i + 1, possible, out, res);
if (res.size() == oldSize) possible[i + 1] = false;
out.resize(out.size() - word.size() - 1);
}
}
}
};

  

类似题目:

[LeetCode] 139. Word Break 单词拆分

All LeetCode Questions List 题目汇总

[LeetCode] 140. Word Break II 单词拆分II的更多相关文章

  1. leetcode 140. Word Break II ----- java

    Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each ...

  2. Java for LeetCode 140 Word Break II

    Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each ...

  3. Leetcode#140 Word Break II

    原题地址 动态规划题 令s[i..j]表示下标从i到j的子串,它的所有分割情况用words[i]表示 假设s[0..i]的所有分割情况words[i]已知.则s[0..i+1]的分割情况words[i ...

  4. [LeetCode] 139. Word Break 单词拆分

    Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine ...

  5. leetcode 139. Word Break 、140. Word Break II

    139. Word Break 字符串能否通过划分成词典中的一个或多个单词. 使用动态规划,dp[i]表示当前以第i个位置(在字符串中实际上是i-1)结尾的字符串能否划分成词典中的单词. j表示的是以 ...

  6. Java实现 LeetCode 140 单词拆分 II(二)

    140. 单词拆分 II 给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中.返回所有这些可能的句子. 说明: 分 ...

  7. 140. Word Break II(hard)

    欢迎fork and star:Nowcoder-Repository-github 140. Word Break II 题目: Given a non-empty string s and a d ...

  8. 【LeetCode-面试算法经典-Java实现】【139-Word Break(单词拆分)】

    [139-Word Break(单词拆分)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a string s and a dictionary of w ...

  9. 【LeetCode】140. Word Break II

    Word Break II Given a string s and a dictionary of words dict, add spaces in s to construct a senten ...

随机推荐

  1. Nastya Hasn't Written a Legend(Codeforces Round #546 (Div. 2)E+线段树)

    题目链接 传送门 题面 题意 给你一个\(a\)数组和一个\(k\)数组,进行\(q\)次操作,操作分为两种: 将\(a_i\)增加\(x\),此时如果\(a_{i+1}<a_i+k_i\),那 ...

  2. 2019安徽省程序设计竞赛 I.你的名字(序列自动机)

    这题和今年南昌邀请网络预选赛M题很像啊,不过主串数量不是一个了 都是在主串中判断子串是不是属于主串的一个子序列 #include <iostream> #include <cstri ...

  3. 项目Alpha冲刺--6/10

    项目Alpha冲刺--6/10 作业要求 这个作业属于哪个课程 软件工程1916-W(福州大学) 这个作业要求在哪里 项目Alpha冲刺 团队名称 基于云的胜利冲锋队 项目名称 云评:高校学生成绩综合 ...

  4. pandas 5 str 参考:https://mp.weixin.qq.com/s/Pwz9iwmQ_YQxUgWTVje9DQ

    str的常用方法 方法 描述 cat() 连接字符串 split() 在分隔符上分割字符串 rsplit() 从字符串末尾开始分隔字符串 get() 索引到每个元素(检索第i个元素) join() 使 ...

  5. 韩顺平老师java视频全套-java视频教程下载

    解压压缩包会有一个种子文件.直接迅雷下载即可,包含了韩顺平老师的java入门视频,jdbc,jsp,servlet,oracle,hibermate,spring,SHH框架,struct,linux ...

  6. 利用GitHub+Node.js+Hexo搭建个人博客

    本篇是自己在搭建Hexo博客平台时的一个过程记录.(2019.9.13实测有效) GitHub 账号注册 因为此文所搭建的个人博客是基于GitHub平台服务的,所以首先是注册GitHub,当然已有账号 ...

  7. LeetCode 740. Delete and Earn

    原题链接在这里:https://leetcode.com/problems/delete-and-earn/ 题目: Given an array nums of integers, you can ...

  8. Greenplum常用的gp_toolkit & pg_catalog监控语句

    gp_toolkit 说明 Greenplum数据库提供了一个名为gp_tooikit的管理schema,该schema下有关于查询系统目录,日志文件, 用户创建(databases,schema,t ...

  9. bootstrap导航条组件

    一.导航条模板(官方文档) <nav class="navbar navbar-default"> <div class="container-flui ...

  10. P1071 潜伏者

    //Pro:NOIP2009 T1 P1071 潜伏者 #include<iostream> #include<cstdio> #include<cstring> ...