给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
题解
题解转载自吴彦祖
这一看就是个最优组合问题,可以使用背包的解题思路
1.初始化 dp=[False,⋯,False],长度为 n 为字符串长度。
dp[i] 表示 s 的前 i 位是否可以用 wordDict 中的单词表示。
2.初始化 dp[0]=True,空字符可以被表示。
3.遍历字符串的所有子串,遍历开始索引 i,遍历区间 [0,n):
4.遍历结束索引 j,遍历区间 [i+1,n+1):
若 dp[i]=True 且 s[i,⋯,j) 在 wordlist 中:dp[j]=True。
解释:
dp[i]=True 说明 s 的前 i 位可以用 wordDict 表示,则 s[i,⋯,j) 出现在 wordDict 中,说明 s 的前 j 位可以表示。
5.返回 dp[n]
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
int len = s.length();
//dp[i]:s的前i个字母和wordDict中字母成功匹配 dp[i]对应于s[0:i-1]
//dp[0]表示空串,并为true,这样才能使后续匹配进行
boolean[] dp = new boolean[len+1];
Set<String> map = new HashSet<>(wordDict);
//初始化 表示空串且合法
dp[0]=true;
for(int i=0;i<=len;i++){
for(int j=i+1;j<=len;j++){
//s[i:j-1]
String temp = s.substring(i,j);
if(map.contains(temp)){
//dp[i] s[0:i-1]
//dp[j] s[0:j-1]
dp[j]=dp[j]||dp[i];
}
}
}
return dp[len];
}
}