题目描述

题解
// 动态规划
// 如果希望"leetcode"可以拆分,那么一定存在子字符串可以匹配,
// 这个子字符串可能是"l",可能是"le",可能是"lee",也可能是"leet",
// 我们构造boolean dp数组,用双for循环遍历s字符串的字符,i索引从头
// 到尾遍历子字符的右边界。j从i-1往左,遍历s的每个子字符的起始点。
// 如果对于"leetcode"来说,i j遍历到可以匹配的子字符串为"leet"(即"leet"
// 在wordDict中出现了),那么我们将dp[i]对应位置置true,此时dp[i]对应的
// 字符位置为"c"(s.substring(0, 5)才等于"leet",取不到下标5)。如下:
//
// set = {"leet", "code"}
// s = "leetcode"
// j i
//
// 0 1 2 3 4 5 6 7 8 9
// dp={true, false, false, false, false, true, false, false, false, false}
// <- j i ->
//
// 实际上我们是判断s.substring(j, i)是否存在于wordDict,和dp[j]是否为true,
// 是否同时成立,成立则赋给dp[i]。dp[j]=true表示上一个子字符是否匹配的标记位,
// (从头遍历的"leet",所以上一个子字符串默认为"",所以dp[0]初始化为0),
// 也就是说,不仅需要判断"leet"是否匹配,还要从j索引对应的"l"开始截断,
// 判断"l"之前的上一个子字符串是否匹配。如果同时匹配,则置当前dp[i]为true,
// 继续循环遍历下去。
// 最后当dp[dp.length]位置为true,说明一定可以能够匹配wordDict的若干个子串,
// 他们能够拼接成s字符串。返回dp[dp.length]/dp[s.length()]即可。
class Solution {
public HashSet<String> set
public boolean wordBreak(String s, List<String> wordDict) {
boolean[] dp = new boolean[s.length() + 1]
set = new HashSet(wordDict)
dp[0] = true
for(int i = 1
for(int j = i - 1
dp[i] = dp[j] && check(s.substring(j, i))
if(dp[i])
break
}
}
return dp[s.length()]
}
public boolean check(String s) {
return set.contains(s)
}
}