提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
题目描述
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。
说明:
分隔时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
示例 1:
输入:
s = “catsanddog”
wordDict = [“cat”, “cats”, “and”, “sand”, “dog”]
输出:
[
“cats and dog”,
“cat sand dog”
]
示例 2:
输入:
s = “pineapplepenapple”
wordDict = [“apple”, “pen”, “applepen”, “pine”, “pineapple”]
输出:
[
“pine apple pen apple”,
“pineapple pen apple”,
“pine applepen apple”
]
解释: 注意你可以重复使用字典中的单词。
示例 3:
输入:
s = “catsandog”
wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出:
[]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-break-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题过程
解题思路
此题我采用递归回溯的方法:首先将所有词典放进HashSet中以便以后判断。
在递归中:递归地分割字符串,由此可能会产生非常多种分割可能,但不是所有分割都是符合题意的。对于不在HashSet里的字符串,直接跳过而不进行收集。需要注意的是:递归函数调用后意味着回到上一层,此时要删除当前层所加入的内容,否则会产生相同内容出现多次的现象。递归返回条件为字符串遍历到结尾,即递归变量等于字符串长度。
注意:如果按照List的形式转化字符串会带有 [ 和 ] 以及逗号,因此要将这些无关的东西去掉。
class Solution {
Set set = new HashSet();
List<String> res = new ArrayList<>();
public List<String> wordBreak(String s, List<String> wordDict) {
for (int i = 0; i < wordDict.size(); i++) {
set.add(wordDict.get(i));
}
List<String> s_list = new ArrayList<>();
dfs(0, s, s_list);
return res;
}
void dfs(int i, String s, List<String> str_list){
if (i == s.length()){
// System.out.println(str_list);
String temp = str_list.toString().replace(",", "");
temp = temp.toString().replace("[", "");
temp = temp.toString().replace("]", "");
res.add(temp);
return;
}
for (int j = i; j < s.length(); j++) {
if (!set.contains(s.substring(i, j + 1))){
continue;
}
str_list.add(s.substring(i, j + 1));
dfs(j + 1, s, str_list);
str_list.remove(str_list.size() - 1);
}
}
}
总结
递归回溯:实质上是遍历所有,然后根据条件一一剔除。
在本题的字符串各个种类递归的时候分为横向扩展和纵向扩展,横向扩展是以当前递归变量为起点往后连续截取到第j个字符,而纵向扩展则是这个j变量。