Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

Note:

  • The same word in the dictionary may be reused multiple times in the segmentation.
  • You may assume the dictionary does not contain duplicate words.

Example 1:

Input: s = "leetcode", wordDict = ["leet", "code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".

Example 2:

Input: s = "applepenapple", wordDict = ["apple", "pen"]
Output: true
Explanation: Return true because "applepenapple" can be segmented as "apple pen apple".
  Note that you are allowed to reuse a dictionary word.

Example 3:

Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
Output: false

给一个字符串,看是否可以由字典中的单词拆分成以空格隔开的单词序列。

用动态规划DP来解,某一个字符前面的字符串的拆分方法可能有多种,后面的拆分要看前面的拆分组合。

State: dp[i],  表示到字符i时,前面1~i的字符串能否拆分

Function: dp[i] = (dp[i - j] + str[j:i] in dict) for j in range(i), 到字符i能否拆分取决于每一个以i结尾的str[j-i]字符 是否在字典里并且j字符之前的字符串可以拆分

Initialize: dp[0] = true

Return: dp[n], 到最后一个字符n是否能拆分

在截取j 到 i 字符串,判断是否在字典中时,可以先判断字典中的字符串最大长度,超出长度就不用再循环了。

此方法可以告诉我们是否能拆分字典中的单词,但不能给出具体拆分内容。如果要知道具体拆分内容要用DFS,见140题。

Java:

public class Solution {
public boolean wordBreak(String s, Set<String> dict) {
boolean[] f = new boolean[s.length() + 1];
f[0] = true; for(int i=1; i <= s.length(); i++){
for(int j=0; j < i; j++){
if(f[j] && dict.contains(s.substring(j, i))){
f[i] = true;
break;
}
}
} return f[s.length()];
}
}

Java:

public class Solution {
public boolean wordBreak(String s, Set<String> dict) {
boolean[] f = new boolean[s.length() + 1];
f[0] = true; for(int i = 1; i <= s.length(); i++){
for(String str: dict){
if(str.length() <= i){
if(f[i - str.length()]){
if(s.substring(i-str.length(), i).equals(str)){
f[i] = true;
break;
}
}
}
}
} return f[s.length()];
}
}  

Java:

public boolean wordBreak(String s, Set<String> dict) {
if(s==null || s.length()==0)
return true;
boolean[] res = new boolean[s.length()+1];
res[0] = true;
for(int i=0;i<s.length();i++)
{
StringBuilder str = new StringBuilder(s.substring(0,i+1));
for(int j=0;j<=i;j++)
{
if(res[j] && dict.contains(str.toString()))
{
res[i+1] = true;
break;
}
str.deleteCharAt(0);
}
}
return res[s.length()];
}

Python:

class Solution(object):
def wordBreak(self, s, wordDict):
n = len(s) max_len = 0
for string in wordDict:
max_len = max(max_len, len(string)) can_break = [False for _ in xrange(n + 1)]
can_break[0] = True
for i in xrange(1, n + 1):
for j in xrange(1, min(i, max_len) + 1):
if can_break[i-j] and s[i-j:i] in wordDict:
can_break[i] = True
break return can_break[-1]

Python: wo

class Solution(object):
def wordBreak(self, s, wordDict):
"""
:type s: str
:type wordDict: List[str]
:rtype: bool
"""
n = len(s)
dp = [False] * (n + 1)
dp[0] = True
for i in xrange(1, n + 1):
for j in xrange(0, i):
if dp[j] and s[j:i] in wordDict:
dp[i] = True
break return dp[-1]   

C++:

class Solution {
public:
bool wordBreak(string s, unordered_set<string>& wordDict) {
const int n = s.length(); size_t max_len = 0;
for (const auto& str: wordDict) {
max_len = max(max_len, str.length());
} vector<bool> canBreak(n + 1, false);
canBreak[0] = true;
for (int i = 1; i <= n; ++i) {
for (int l = 1; l <= max_len && i - l >= 0; ++l) {
if (canBreak[i - l] && wordDict.count(s.substr(i - l, l))) {
canBreak[i] = true;
break;
}
}
} return canBreak[n];
}
};

Followup: 返回其中的一个解,如果要返回全部解需要用140. Word Break II的方法,一个解要简单很多。F jia

Java:

class Solution {
public String wordBreak(String s, Set<String> dict) {
if (s == null || s.isEmpty() || dict == null) {
return "";
} boolean[] dp = new boolean[s.length() + 1];
String[] words = new String[s.length() + 1];
dp[0] = true;
words[0] = ""; for (int i = 1; i <= s.length(); i++) {
for (int j = 0; j < i; j++) {
if (dp[j] && dict.contains(s.substring(j, i))) {
dp[i] = true;
if (words[j].isEmpty()) {
words[i] = s.substring(j, i);
} else {
words[i] = words[j] + " " + s.substring(j, i);
}
}
}
}
if (dp[s.length()]) {
return words[s.length()];
} else {
return "";
}
} public static void main(String[] args) {
String s = new String("catsanddog");
String[] d = {"cat", "cats", "and", "sand", "dog"};
Set<String> dict = new HashSet<String>();
dict.addAll(Arrays.asList(d));
System.out.println(s);
System.out.println(dict);
Solution sol = new Solution();
System.out.println(sol.wordBreak(s, dict));
}
}

  

类似题目:

[LeetCode] 140. Word Break II 单词拆分II

[LeetCode] 97. Interleaving String 交织相错的字符串

All LeetCode Questions List 题目汇总

[LeetCode] 139. Word Break 单词拆分的更多相关文章

  1. LeetCode 139. Word Break单词拆分 (C++)

    题目: Given a non-empty string s and a dictionary wordDict containing a list of non-emptywords, determ ...

  2. [leetcode]139. Word Break单词能否拆分

    Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine ...

  3. 139 Word Break 单词拆分

    给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,确定 s 是否可以被空格分割为一个或多个在字典里出现的单词.你可以假设字典中无重复的单词.例如,给出s = "leet ...

  4. leetcode 139. Word Break 、140. Word Break II

    139. Word Break 字符串能否通过划分成词典中的一个或多个单词. 使用动态规划,dp[i]表示当前以第i个位置(在字符串中实际上是i-1)结尾的字符串能否划分成词典中的单词. j表示的是以 ...

  5. Leetcode#139 Word Break

    原题地址 与Word Break II(参见这篇文章)相比,只需要判断是否可行,不需要构造解,简单一些. 依然是动态规划. 代码: bool wordBreak(string s, unordered ...

  6. [LeetCode] 139. Word Break 拆分词句

    Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine ...

  7. Leetcode139. Word Break单词拆分

    给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词. 说明: 拆分时可以重复使用字典中的单词. 你可以假设字典中没有重复 ...

  8. leetcode 139. Word Break ----- java

    Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separa ...

  9. LeetCode #139. Word Break C#

    Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separa ...

随机推荐

  1. ThinkPHP的路由规则和URL生成,结合django的URL理解

    这个知识点,我觉得蛮重要的. 不作任何路由定义的TP,URL格式和controller之间,相当于强绑定. 路由配置,让URL和controller的关系可以自定义. URL生成,让controlle ...

  2. nginx1.15.10配置使用非https访问返回403

    nginx版本号:nginx version: nginx/1.15.10 server { listen 443 default ssl; server_name app.test.com; if ...

  3. canvas绚丽的随机曲线

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAyMAAAHECAIAAAClb2KBAAAgAElEQVR4nOyd+VsaV/v/Pz/UpW3abJ ...

  4. django-配置静态页面-celery/redis/nginx

    celery生成静态页面 celery_tasks/tasks.py # 生成静态首页 from django.template import loader, RequestContext # tem ...

  5. (尚018-第二章2.1)Vue使用vue-cli创建模板项目

    2.1.1 1)vue-cli是官方提供的脚手架工具(注意:脚手架本身是个库) 2)github:https://github.com/vuejs/vue-cli 3)作用:从https://gith ...

  6. 如何用okr做好目标规划

    有朋友和我吐槽公司总是规划一个个振奋人心的目标,让大家对工作充满了热情.然而好的开头却缺少追踪反馈没有好的结尾,那些大家所渴望达成的目标随着时间的流逝便逐渐没有了音信,不再有人主动提起,团队成员迎来的 ...

  7. cjss 像编写css 一样开发web应用

    cjss 提供了使用类似css 的方式编写web 应用 cjss 包含的阶段 data prepare body element 几点说明 并不是所以阶段必须使用,但是每个级别只能存在一个script ...

  8. mybatis的判定时间字段问题 java.lang.IllegalArgumentException: invalid comparison: cn.hutool.core.date.DateTime and java.lang.String

    今天听组员说: mybatis在3.30版本及以上判定时间时 <if test="date_time != null and date_time != '' "> da ...

  9. 3-微信小程序开发(小程序的目录结构说明)

    https://www.cnblogs.com/yangfengwu/p/10050784.html 源码下载链接: 或者 这节先说一下小程序的目录结构 自行根据  https://www.cnblo ...

  10. Linux 系统管理——账号管理

    一.用户账号管理 1.用户账户概述 用户账户的常见分类: 超级用户:root  uid=0  gid=0  权限最大 普通用户:uid>=500  做一般权限的系统管理,权限有限. 程序用户:1 ...