题目:https://leetcode.cn/problems/word-break/description/?favorite=2cktkvj
139. 单词拆分
中等
给你一个字符串 s
和一个字符串列表 wordDict
作为字典。请你判断是否可以利用字典中出现的单词拼接出 s
。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
示例 1:
输入: s = "leetcode", wordDict = ["leet", "code"] 输出: true 解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。
示例 2:
输入: s = "applepenapple", wordDict = ["apple", "pen"] 输出: true 解释: 返回 true 因为"
applepenapple"
可以由"
apple" "pen" "apple" 拼接成
。 注意,你可以重复使用字典中的单词。
示例 3:
输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"] 输出: false
参考:参考链接
KEY:单纯使用DFS发现大部分通过了,但是部分样例超时了
public class Solution {
String s;
List<String> wordDict;
int n;
boolean res = false;
public boolean wordBreak(String s, List<String> wordDict) {
this.s = s;
this.wordDict = wordDict;
n = s.length();
for(int i=0;i<n;i++)
{
dfs(0,i);
}
return res;
}
void dfs(int start,int end)
{
//[start,end]期间是否可以作为一个单词
String subString = s.substring(start,end+1);
if(wordDict.contains(subString))
{
if(end == n-1)
{
//结束了
res = true;
return;
}
for(int i=end+1;i<n;i++)
dfs(end+1,i);
}
}
public static void main(String[] args) {
Solution s = new Solution();
System.out.println(s.wordBreak("leetcode", Arrays.asList("leet","code")));
}
}
直接用记忆化搜索补救!
加入dp[][]//进行缓存
public class Solution {
int[][] dp;
String s;
List<String> wordDict;
int n;
boolean res = false;
public boolean wordBreak(String s, List<String> wordDict) {
this.s = s;
this.wordDict = wordDict;
this.dp = new int[n+1][n+1];//1->true,0->null,-1->false
Arrays.fill(dp,0);
n = s.length();
for(int i=0;i<n;i++)
{
dfs(0,i);
}
return res;
}
void dfs(int start,int end)
{
//[start,end]期间是否可以作为一个单词
String subString = s.substring(start,end+1);
if(wordDict.contains(subString))
{
dp[start][end] = 1;
if(end == n-1)
{
//结束了
res = true;
return;
}
for(int i=end+1;i<n;i++)
{
if(dp[end+1,n-1] == 1)
dfs(end+1,i);
}
}
dp[start][end] =-1;
}
public static void main(String[] args) {
Solution s = new Solution();
System.out.println(s.wordBreak("leetcode", Arrays.asList("leet","code")));
}
}