这题我主要用的思想是:动态规划
1.状态表示:以i位置为结尾的字符串是否可以用字典表示,然后就可以拆分成 j ~ i 为字典中的最后一个单词,此时 0 <= j <= i (1.有可能全部为字典的一个单词,2.有可能只有一个字母的单词),然后就可以化为以 j - 1位置结尾可以被字典表示 和 j ~ i为字典中的元素,二者都符合则以i位置可以被字典表示。
2.状态转移方程: dp[i] = dp[j - 1] && string.substring(j, i + 1)
3.初始化: 防止j - 1越界,初始化dp[0] = true,然后j就只需要从1判断
4.填表顺序: 为了填写当前状态的时候,所需要的状态已经填写完成,从左到右
5.返回值: 以length - 1结尾的位置是否符合状态表示
6.细节问题: 1.hash表就可以当成字典使用,2.找到第一个能使dp[i] = true的时候就不要让j再往前找了。
public boolean wordBreak(String s, List<String> wordDict) {
HashSet<String> hashSet = new HashSet<>(wordDict);//用于搜索
int n = s.length();
boolean[] dp = new boolean[n + 1];
dp[0] = true;//防止越界,但不影响后续
s = " " + s;//下标对应[1] 对应 [1] 处理映射
for (int i = 0; i < n; i++) {
// >= 1 表示不需要判断占位符
for (int j = i; j >= 1; j--) {
//往前找一直找到 以j - 1结尾的能被字典所拼为止找不到直接返回false,不必判断j~i
if (dp[j - 1] == true && hashSet.contains(s.substring(j, i + 1))){
dp[i] = true;
//只要找到一种符合条件即可 其他的无需判断
break;
}else {
dp[i] = false;
}
}
}
return dp[n];
}
上述代码else可以省略因为boolean的默认值是false,dp[j - 1] == true 可转换为 dp[j - 1],因为true == true 返回true,false == true 返回false。