在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]; } };