# word-break-ii(单词切分2)

<center>知识点:动态规划</center>


## 题目描述
Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.

Return all such possible sentences.

For example, given
s ="catsanddog",
dict =["cat", "cats", "and", "sand", "dog"].

A solution is["cats and dog", "cat sand dog"].

-----

给定字符串s和单词字典dict,在s中添加空格以构造一个句子,其中每个单词都是有效的字典单词。

返回所有这些可能的句子。

比如:
s ="catsanddog",
dict =["cat", "cats", "and", "sand", "dog"].

应该返回["cats and dog", "cat sand dog"].

## 解题思路

我们从某一个位置`index`将`s`切分为前后两个部分,分别记为`s1`和`s2`,如果`s1`在`dict`中,我们去计算`s2`计算的结果,然后将`s2`切分的结果与`s1`合并即可,如果`s2`不能切割,我们就从`index+1`继续对`s`进行切割,实际是一种`dfs`的思想,核心思想如下:

```java
ArrayList<String> wordBreak(String s, Set<String> dict){
	ArrayList<String> res;
  for(int index=1;index<s.length;index++){
    if(dict.contains(s[0:index])){
      ArrayList<String> list=wordBreak(s[index:],dict);
      if(list==null){
        continue;
      }else{
        res+=merge(s[0:index],list);
      }
    }
  }
  return res;
}
```

这样虽然可以解决问题,但是有点小瑕疵,考虑:`s="abcdefg"`,`dict={"bc","def","g"}`,那么:

- index=1 s1=a s2=bcdefg ,切割bcdefg
- Index=2 s1=ab s2=cdefg,切割cdefg
- index=3 s1=abc s2=defg,切割defg
- ...

注意,第一步切割`bcdefg`的时候递归调用了`wordBreak`,在切割`bcdefg`的时候也会切割`cdefg`、`defg`、`efg`、`fg`、`g`,然后下面几步也是类似的操作,所以说下面几步实际上做了一部分重复的工作,为了避免这种重复的工作,我们可以使用`Map`,将`s`与其切分的结果存下来,这样下次再遇到`s`的时候直接从`map`中取之前分好的结果就行了,不用做重复操作。


## 代码

[这里](../src/twelve/Solution.java)