在DP的时候记录前驱节点的值到数组,然后DFS该数组构造结果。做完这道题,有种“宋元明清后,王朝至此完”的赶脚。
import java.util.*;
public class Solution {
public ArrayList<String> wordBreak(String s, Set<String> dict) {
int len = s.length();
boolean f[] = new boolean[len + 1];
ArrayList<ArrayList<Integer>> prev = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i <= len; i++) {
prev.add(new ArrayList<Integer>());
}
f[0] = true;
for (int i = 1; i <= len; i++) {
for (int j = i - 1; j >= 0; j--) {
if (f[j] && dict.contains(s.substring(j, i))) {
prev.get(i).add(j);
f[i] = true;
}
}
}
ArrayList<String> result = new ArrayList<String>();
buildResult(s, prev, len, result, "");
return result;
}
private void buildResult(String s, ArrayList<ArrayList<Integer>> prev, int end, ArrayList<String> result, String current) {
ArrayList<Integer> prevs = prev.get(end);
for (int i = 0; i < prevs.size(); i++) {
int n = prevs.get(i);
String sub = s.substring(n, end);
String r = sub;
if (!current.equals("")) {
r = r + " " + current;
}
if (n == 0) {
result.add(r);
}
else {
buildResult(s, prev, n, result, r);
}
}
}
}
第二刷,DFS果然超时,但是DFS之前先用DP记录什么子串是不能成功的,可以减少试错,但仍然是上面的方法好:
class Solution {
public:
vector<string> wordBreak(string s, unordered_set<string> &dict) {
vector<string> res;
if (!wordBreakPossible(s, dict)) return res;
wordBreakRe(s, dict, 0, res, "");
return res;
}
void wordBreakRe(string &s, unordered_set<string> &dict, int idx,
vector<string> &result, string tmp)
{
if (idx == s.size())
{
result.push_back(tmp);
return;
}
if (idx != 0) tmp.push_back(' ');
for (int i = idx; i < s.size(); i++)
{
string sub = s.substr(idx, i - idx + 1);
if (dict.find(sub) != dict.end())
{
wordBreakRe(s, dict, i + 1, result, tmp+sub);
}
}
}
bool wordBreakPossible(const string &s, const unordered_set<string> &dict) {
int N = s.size();
vector<bool> possible;
possible.resize(N + 1);
possible[0] = true; // s with len == 0
for (int i = 1; i <= N; i++)
{
for (int j = 0; j < i; j++)
{
string sub = s.substr(j, i - j);
if (possible[j] && dict.find(sub) != dict.end())
{
possible[i] = true;
}
}
}
return possible[N];
}
};