139. 单词拆分
程序员文章站
2022-03-24 14:12:22
...
题目:
题解:
- 解释一:
- 解释二:
/*
动态规划算法,dp[i]表示s前i个字符能否拆分
转移方程:dp[j] = dp[i] && check(s[i+1, j]);
check(s[i+1, j])就是判断i+1到j这一段字符是否能够拆分
其实,调整遍历顺序,这等价于s[i+1, j]是否是wordDict中的元素
这个举个例子就很容易理解。
假如wordDict=["apple", "pen", "code"],s = "applepencode";
dp[8] = dp[5] + check("pen")
翻译一下:前八位能否拆分取决于前五位能否拆分,加上五到八位是否属于字典
(注意:i的顺序是从j-1 -> 0哦~
*/
代码:
1. 常规代码:
import java.util.*;
public class code139 {
// 常规代码:
public static boolean wordBreak(String s, List<String> wordDict) {
Set<String> wordDictSet = new HashSet<>(wordDict);
// dp[i] 表示字符串 s 前 i 个字符组成的字符串 s[0..i-1] 是否能被空格拆分成若干个字典中出现的单词
boolean dp[] = new boolean[s.length() + 1];
dp[0] = true; // dp[0] = true 表示空串且合法
for(int i = 1; i <= s.length(); i++)
{
for(int j = 0; j < i; j++)
{
if(dp[j] && wordDictSet.contains(s.substring(j, i)))
{
dp[i] = true;
break; // break退出的是内层的for循环
}
}
}
return dp[s.length()];
}
public static void main(String[] args) {
String s1 = "leetcode";
List<String> wordDict1 = new ArrayList<String>();
wordDict1.add("leet");
wordDict1.add("code");
boolean res1 = wordBreak(s1, wordDict1);
System.out.println(res1);
String s2 = "applepenapple";
List<String> wordDict2 = new ArrayList<String>();
wordDict2.add("apple");
wordDict2.add("pen");
boolean res2 = wordBreak(s2, wordDict2);
System.out.println(res2);
String s3 = "catsandog";
List<String> wordDict3 = new ArrayList<String>();
wordDict3.add("cats");
wordDict3.add("dog");
wordDict3.add("sand");
wordDict3.add("and");
wordDict3.add("cat");
boolean res3 = wordBreak(s3, wordDict3);
System.out.println(res3);
}
}
2. 优化代码:
import java.util.*;
public class code139 {
// 优化代码:
public static boolean wordBreak(String s, List<String> wordDict) {
int minLen = Integer.MAX_VALUE;
int maxLen = 0;
for(int i = 0; i < wordDict.size(); i++)
{
if(wordDict.get(i).length() < minLen)
{
minLen = wordDict.get(i).length(); // 获取最小单词长度
}
if(wordDict.get(i).length() > maxLen)
{
maxLen = wordDict.get(i).length(); // 获取最大单词长度
}
}
Set<String> wordDictSet = new HashSet<>(wordDict);
// dp[i] 表示字符串 s 前 i 个字符组成的字符串 s[0..i-1] 是否能被空格拆分成若干个字典中出现的单词
boolean dp[] = new boolean[s.length() + 1];
dp[0] = true; // dp[0] = true 表示空串且合法
for(int i = minLen; i <= s.length(); i++) // i不用从1开始,只要从wordDict里面字符串(单词)的最小长度开始就行
{
for(int j = Math.max(0, i - maxLen); j <= i - minLen; j++) // 每次并不需要从s[0]开始搜索。因为wordDict中的字符串长度是有限的。只需要从i-maxWordLength开始搜索就可以了。
{
if(dp[j] && wordDictSet.contains(s.substring(j, i)))
{
dp[i] = true;
break; // break退出的是内层的for循环
}
}
}
return dp[s.length()];
}
public static void main(String[] args) {
String s1 = "leetcode";
List<String> wordDict1 = new ArrayList<String>();
wordDict1.add("leet");
wordDict1.add("code");
boolean res1 = wordBreak(s1, wordDict1);
System.out.println(res1);
String s2 = "applepenapple";
List<String> wordDict2 = new ArrayList<String>();
wordDict2.add("apple");
wordDict2.add("pen");
boolean res2 = wordBreak(s2, wordDict2);
System.out.println(res2);
String s3 = "catsandog";
List<String> wordDict3 = new ArrayList<String>();
wordDict3.add("cats");
wordDict3.add("dog");
wordDict3.add("sand");
wordDict3.add("and");
wordDict3.add("cat");
boolean res3 = wordBreak(s3, wordDict3);
System.out.println(res3);
}
}
参考:
上一篇: 比妈妈还凶得那条狗
推荐阅读
-
【LeeCode 简单 字符串 python3】557 反转字符串中的单词 III
-
对sklearn的使用之数据集的拆分与训练详解(python3.6)
-
maya怎么拆分物体UV?
-
AI如何将字体拆开?AI拆分字体笔画
-
python利用多种方式来统计词频(单词个数)
-
flash教程:使用拆分数字和文字的函数
-
华为机试 字符串最后一个单词的长度
-
大数据走入云 VMware拆分新云计算公司
-
python统计文本文件内单词数量的方法
-
经典问题(c++/python)素数、杨辉三角(金字塔型)、统计单词数、简单计算器、密码安全程度、凯撒密码加密、汉诺塔 (python课设实验实例)-- biaobiao88