携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情
题目
给定一个字符串 s 和一个字符串字典 wordDict ,在字符串 s 中增加空格来构建一个句子,使得句子中所有的单词都在词典中。以任意顺序 返回所有这些可能的句子。
注意:词典中的同一个单词可能在分段中被重复使用多次。
示例 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"]
输出:[]
提示
- 1 <= s.length <= 20
- 1 <= wordDict.length <= 1000
- 1 <= wordDict[i].length <= 10
- s 和 wordDict[i] 仅有小写英文字母组成
- wordDict 中所有字符串都 不同
题解
思路
题目给定字典序列 wordDict,我们可以创建一棵前缀树,将字典全部插入到前缀树中
然后查找可以分割的索引位置,进行分割,并对剩下的字符串进行 dfs
步骤:
s = "catsandog" wordDict = ["cats", "dog", "sand", "and", "cat"]
我们将 wordDict 插入到前缀树中
字符串 s 的各个字符对应索引如下:
c a t s a n d o g
0 1 2 3 4 5 6 7 8
- 我们从前往后,通过前缀树查找后,发现 2 和 3 位置可以进行分割,即前面可以分割为 cat 或者 cats
- 我们先分割 2 位置,然后对剩下的字符串 s a n d o g 进行 dfs 同样操作,直到整个字符串都处理完
- 然后我们回溯,再分割 3 位置,然后对剩下的字符串 a n d o g 进行 dfs,直到整个字符串都处理完
- dfs 过程中,我们使用 StringBuilder 进行拼接
但是在以下测试用例超时了:(后面会说明这个用例)
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"]
代码
class Solution {
public List<String> wordBreak(String s, List<String> wordDict) {
trie = new Trie();
for(String str : wordDict){
trie.insert(str);
}
res = new ArrayList<>();
map = new HashMap<>();
dfs(new StringBuilder(), s, 0);
return res;
}
List<String> res;
Trie trie;
private void dfs(StringBuilder sb, String s, int i){
int len = s.length();
if(i == len){
//删除最后一个空格
sb.deleteCharAt(sb.length() - 1);
res.add(sb.toString());
return;
}
int sblen = sb.length();
List<Integer> indexs = trie.search(s, i);
for(int index : indexs){
sb.append(s.substring(i, index + 1)).append(" ");
dfs(sb, s, index + 1);
sb.setLength(sblen);
}
}
}
结语
业精于勤,荒于嬉;行成于思,毁于随。