方法1:切片函数+记忆化搜索
Map<String, List<String>> cache = new HashMap<>();
List<String> wordDict;
public List<String> wordBreak(String s, List<String> wordDict) {
this.wordDict = wordDict;
return dfs(s);
}
private List<String> dfs(String s) {
if (cache.containsKey(s)) {
return cache.get(s);
}
List<String> res = new ArrayList<>();
if (s.length() == 0) {
res.add("");
return res;
}
for (String word : wordDict) {
if (s.startsWith(word)) {
List<String> subList = dfs(s.substring(word.length()));
for (String sub : subList) {
res.add(word + (sub.isEmpty() ? "" : " ") + sub);
}
}
}
cache.put(s, res);
return res;
}
方法2:下标切分+记忆化搜索
Map<Integer, List<String>> cache = new HashMap<>();
List<String> wordDict;
int maxLen = 0;
public List<String> wordBreak(String s, List<String> wordDict) {
this.wordDict = wordDict;
for (String word : wordDict) {
if (word.length() > maxLen) maxLen = word.length();
}
return dfs(s, 0);
}
private List<String> dfs(String s, int start) {
if (cache.containsKey(start)) return cache.get(start);
List<String> res = new ArrayList<>();
if (start == s.length()) res.add("");
for (int i = start; i < start + maxLen && i < s.length(); i++) {
if (wordDict.contains(s.substring(start, i + 1))) {
List<String> remainList = dfs(s, i + 1);
for (String remain : remainList) {
if ("".equals(remain)) res.add(s.substring(start, i + 1));
else res.add(s.substring(start, i + 1) + " " + remain);
}
}
}
cache.put(start, res);
return res;
}
方法3:DP预处理+回溯
List<String> resList = new ArrayList<>();
boolean[] dp;
List<String> wordDict;
public List<String> wordBreak(String s, List<String> wordDict) {
int n = s.length();
this.wordDict = wordDict;
this.dp = new boolean[n + 1];
dp[0] = true;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < i; j++) {
if (dp[j] && wordDict.contains(s.substring(j, i))) {
dp[i] = true;
break;
}
}
}
if (dp[n]) {
dfs(s, n, new ArrayList<>());
return resList;
}
return resList;
}
private void dfs(String s, int index, List<String> levelList) {
if (index == 0) {
StringBuilder sb = new StringBuilder();
for (int i = levelList.size() - 1; i >= 0; i--) {
sb.append(levelList.get(i)).append(" ");
}
sb.deleteCharAt(sb.length() - 1);
resList.add(sb.toString());
return;
}
for (int i = 0; i < index; i++) {
if (dp[i]) {
String sub = s.substring(i, index);
if (wordDict.contains(sub)) {
levelList.add(sub);
dfs(s, i, levelList);
levelList.remove(levelList.size() - 1);
}
}
}
}