题目来源:https://leetcode.com/problems/word-break-ii/
问题描述
140. Word Break II
Hard
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:
[]
------------------------------------------------------------
题意
LeetCode 139. Word Break的姊妹题。给定一个字符串s和一个词表wordDict,判断字符串s能否由词表wordDict中的字符串组成,给出词表中所有字符组合方式,词表wordDict中的字符串可以重复使用。
------------------------------------------------------------
思路
仍是dfs。搜索的时候加一个字符串保存当前的字符串组合,在搜索到s的词尾时将组合字符串加入结果列表。相比于LeetCode 139. Word Break的解答,主要的改动在于vis数组。
由于需要求出所有可行的组合,所以搜索的时候允许访问重复的状态,因为达到状态的路径不同,组合字符串也不同。但是,对于已经判定不能达到s词尾的状态,是不能重复访问的(否则会造成超时),因此vis[i] = true的条件需要修改为状态i被访问过且已判定状态i无法到达词尾。
------------------------------------------------------------
代码
class Solution {
public List<String> wordBreak(String s, List<String> wordDict) {
List<String> ans = new LinkedList<String>();
Collections.sort(wordDict, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s2.length() - s1.length();
}
});
boolean[] vis = new boolean[s.length()+1];
dfs(0, s, wordDict, new String(), ans, vis);
return ans;
}
private boolean dfs(int i, String s, List<String> wordDict, String cur, List<String> ans, boolean[] vis) {
int n = s.length();
if (i == n) {
ans.add(cur.substring(1)); // strip the first blank
return true;
}
boolean flag = false;
for (String word: wordDict) {
int l = word.length();
if (i + l <= n && !vis[i + l] && word.equals(s.substring(i, i + l)) && dfs(i + l, s, wordDict, cur + " " + word, ans, vis)) {
flag = true;
}
}
vis[i] = !flag;
return flag;
}
}