https://leetcode-cn.com/problems/word-break/
给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
说明:拆分时可以重复使用字典中的单词。你可以假设字典中没有重复的单词。
可以采用DFS BFS或者DP来解决 无论采用何种方式,都类似于一种搜索问题。
依次遍历给定字符串的每一个字符串 假定当前遍历位置序号为i,则字符串S此时可以分为两部分s0=s[0, i-1], s1=s[i, s.length] 此时如果满足s0在给定的单词列表中并且s1可以递归继续拆分(s1是S的一个子问题),则S可以被正确拆分。
从字符串0位置出发,依次遍历从0开始的每个位置i,此时s切割为s0, s1 判断s0是否在单词列表中,如果在,递归判断s1是否可以拆解
public boolean wordBreak2(String s, List wordDict) {
Set set = new HashSet<>(wordDict);
return dfs2(s, 0, s.length()-1, set);
}
private boolean dfs2(String s, int start, int length, Set set) {
if (start > length) return true;
for (int i=start+1; i<=length+1; i++) {
String prex = s.substring(start, i);
System.out.println(prex+" " + i + " " + length);
if (set.contains(prex) && dfs2(s, i, length, set)) {
return true;
}
}
return false;
}
优化一下,判断s1子问题时,对于s1来说,需要从起始位置start 再次拆分, 可以记录之前start位置的记录结果,如果已经计算直接返回,避免重复计算
// DFS+记忆化
public boolean wordBreak3(String s, List wordDict) {
Set set = new HashSet<>(wordDict);
Boolean[] flag = new Boolean[s.length()+1];
return dfs3(s, 0, s.length()-1, set, flag);
}
private boolean dfs3(String s, int start, int length, Set set, Boolean[] flag) {
if (start > length) return true;
if (flag[start] != null) return flag[start];
for (int i=start+1; i<=length+1; i++) {
String prex = s.substring(start, i);
if (set.contains(prex) && dfs3(s, i, length, set, flag)) {
flag[start] = true;
return true;
}
}
flag[start] = false;
return false;
}
从0位置触发 依次遍历每一个位置i 此时字符串被拆分成两个部分s0, s1 如果s0在单词列表中,说明i可能是一种可行的拆分方式,观察i的位置 如果i是字符串结尾 则直接返回true 表示已经正确拆分,如果不是则将i放入队列中,等待从i位置开始处理下一个子问题。
public boolean wordBreak4(String s, List wordDict) {
Set set = new HashSet<>(wordDict);
Queue queue = new LinkedList<>();
queue.add(0);
while (!queue.isEmpty()) {
int start = queue.poll();
for (int i=start+1; i<=s.length(); i++) {
String prex = s.substring(start, i);
System.out.println(prex+" " + i + " " + start);
if (set.contains(prex)) {
if (i
优化,记录已经访问过的问题
// BFS优化
public boolean wordBreak5(String s, List wordDict) {
Set set = new HashSet<>(wordDict);
boolean[] flag = new boolean[s.length()+1];
Queue queue = new LinkedList<>();
queue.add(0);
while (!queue.isEmpty()) {
int start = queue.poll();
if (flag[start]) continue;
flag[start] = true;
for (int i=start+1; i<=s.length(); i++) {
String prex = s.substring(start, i);
System.out.println(prex+" " + i + " " + start);
if (set.contains(prex)) {
if (i
https://leetcode-cn.com/problems/word-break/solution/dan-ci-chai-fen-by-leetcode-solution/
// DP
public boolean wordBreak1(String s, List wordDict) {
Set set = new HashSet<>(wordDict);
boolean[] dp = new boolean[s.length()+1];
dp[0] = true;
for (int i=1; i<=s.length(); i++) {
for (int j=0; j