题目:

Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

For example, given
s = "leetcode",
dict = ["leet", "code"].

Return true because "leetcode" can be segmented as "leet code".

解题思路:

这是一道DP题,说实话,本人也是算法方面的菜鸟一枚,关于DP方面的题,还不太会解,没办法,只能多练习了。

这里采用DP中的两种方式实现:自顶向下和自底向上。

dp[i]表示前i个字符能否进行Wordbreak。当求解dp[i]时,可利用已经求解的dp[i-1],dp[i-2]…dp[1],dp[0]进行求解。

对于dp[n]的求解,我们可以将n个字符进行切分求解,分为前i个字符和后n-i个字符,i可以为(0,1,2,3,4…n-1)

假设i为1时,可根据dp[i]和后面的n-1个字符组成的单词是否在dict中来判断dp[n],只要i(0,1,2,3,4…n-1)其中一种

情况为真,则dp[n]为true,表示可以进行workbreak。

实现代码:

#include <iostream>
#include <string>
#include <vector>
#include <unordered_set>
using namespace std; /*
Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words. For example, given
s = "leetcode",
dict = ["leet", "code"]. Return true because "leetcode" can be segmented as "leet code".
*/
class Solution {
public:
bool wordBreak(string s, unordered_set<string> &dict) {
if(s.size() == || dict.size() == )
return false;
int len = s.size();
vector<bool> dp(len+, false);//保存状态,dp[i]表示前i个字符是否可以进行wordBread
dp[] = true;
for(int i = ; i <= len; i++)
for(int j = ; j < i; j++)
{
if(dp[j] && dict.count(s.substr(j, i-j)) == )//对前i个字符进行切分时,只要有一种情况为true,则dp[i]=true
{
dp[i] = true;
break;
}
}
return dp[len]; } bool wordBreak2(string s, unordered_set<string> &dict) {
if(s.size() == || dict.size() == )
return false;
int len = s.size();
vector<bool> dp(len+, false);//保存状态,dp[i]表示前i个字符是否可以进行wordBread
dp[] = true;
for(int i = ; i < len; i++)
if(dp[i])
{
for(int j = ; j <= len-i; j++)
if(dict.count(s.substr(i, j)) == )
dp[i+j] = true;
} return dp[len]; } //DP:自顶向下,
int wordBreak3_core(string s, unordered_set<string> &dict, int *dp)
{
int len = s.size();
if(dp[len] >= )
return dp[len];//如果值已经改变即不再是初始值,说明dp[len]已经求得,直接返回即可,不必再求
int isBreak;
if(len == )
isBreak = ;
else
{
int ret = ;
for(int i = ; i < len; i++)
{
if(wordBreak3_core(s.substr(, i), dict, dp) == && dict.count(s.substr(i, len-i)) == )
{
ret = ;
break;
} }
isBreak = ret; }
dp[len] = isBreak;
return isBreak;
}
//DP:自顶向下,
bool wordBreak3(string s, unordered_set<string> &dict)
{
if(s.size() == || dict.size() == )
return false;
int len = s.size();
int *dp = new int[len+];//保存状态,dp[i]表示前i个字符是否可以进行wordBread
for(int i = ; i <= len; i++)
dp[i] = -;//每个状态进行初始化
int ret = wordBreak3_core(s, dict, dp);
delete [] dp;
return ret; } }; int main(void)
{
string s("leetcode");
unordered_set<string> dict;
dict.insert("leet");
dict.insert("code");
Solution solution;
bool ret = solution.wordBreak3(s, dict);
cout<<ret<<endl; return ;
}

网上还有通过trie树实现的,这里直接引用http://www.iteye.com/topic/1132188#2402159,就不多写了

代码如下:

class Solution {
public: class Node {
public:
Node* next[];
bool end;
Node(): end(false) { for (int i = ; i < ; i++) next[i] = NULL;}
void insert(string a) {
Node * cur = this;
for (int i = ; i < a.size(); i++) {
if (cur->next[a[i]-'a'] == NULL) {
cur->next[a[i]-'a'] = new Node();
}
cur = cur->next[a[i]-'a'];
}
cur->end = true;
}
~Node () {
for (int i = ;i < ; i++) delete next[i];
}
}; bool wordBreak(string s, unordered_set<string> &dict) {
Node root;
for (auto it = dict.begin(); it != dict.end(); ++it) {
root.insert(*it);
} vector<bool> v(s.size(), false);
findMatch(s, &root, , v);
for (int i = ; i < s.size(); i++)
if (v[i]) findMatch(s, &root, i+, v);
return v[s.size() - ];
} void findMatch(const string& s, Node* cur, int start, vector<bool> &v) {
int i = start, n = s.size();
while (i < n) {
if (cur->next[s[i] - 'a'] != NULL) {
if (cur->next[s[i] - 'a']->end) v[i] = true;
cur = cur->next[s[i] - 'a'];
}
else break;
i++;
} }
};

LeetCode139:Word Break的更多相关文章

  1. LeetCode之“动态规划”:Word Break && Word Break II

     1. Word Break 题目链接 题目要求: Given a string s and a dictionary of words dict, determine if s can be seg ...

  2. LeetCode140:Word Break II

    题目: Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where e ...

  3. leetcode笔记:Word Break

    一. 题目描写叙述 Given a string s and a dictionary of words dict, determine if s can be segmented into a sp ...

  4. [LeetCode] Word Break II 拆分词句之二

    Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each ...

  5. word break和word wrap

    默认情况下,如果同一行中某个单词太长了,它就会被默认移动到下一行去: word break(normal | break-all | keep-all):表示断词的方式 word wrap(norma ...

  6. 17. Word Break && Word Break II

    Word Break Given a string s and a dictionary of words dict, determine if s can be segmented into a s ...

  7. LeetCode:Word Break II(DP)

    题目地址:请戳我 这一题在leetcode前面一道题word break 的基础上用数组保存前驱路径,然后在前驱路径上用DFS可以构造所有解.但是要注意的是动态规划中要去掉前一道题的一些约束条件(具体 ...

  8. LeetCode Word Break II

    原题链接在这里:https://leetcode.com/problems/word-break-ii/ 题目: Given a string s and a dictionary of words  ...

  9. Leetcode#139 Word Break

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

随机推荐

  1. pidgin的未认证解决办法

    安全验证打开还是无法登陆,并且手机无法验证. 解决:开启手机二次验证,给pidgin设置专门的登陆账户密码,即可解决.

  2. nyoj86-找球号(一) 【set 二分查找 hash】

    http://acm.nyist.net/JudgeOnline/problem.php?pid=86 找球号(一) 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 ...

  3. 6.ZigZag Conversion(Graph, traverse)

    The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...

  4. TZOJ 1840 Jack Straws(线段相交+并查集)

    描述 In the game of Jack Straws, a number of plastic or wooden "straws" are dumped on the ta ...

  5. jQuery html5Validate基于HTML5表单验证插件

    更新于2016-02-25 前面提到的新版目前线上已经可以访问: http://mp.gtimg.cn/old_mp/assets/js/common/ui/Validate.js demo体验狠狠地 ...

  6. Spring_AOP动态代理详解(转)

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  7. 利用telnet模拟http请求

    最近准备接触php socket编程,所以准备先巩固以前学到的知识, 这里先简单回顾下 利用telnet 来模拟http请求. 1.先在80端口指向的目录建立http.php 文件 2.在终端输入 t ...

  8. 【每日更新】【SQL实用大杂烩】

    11.分页1. select * from (select top 2 * from( select top 3 * from t_table order by field1) a order by  ...

  9. LINQ to Entities 不支持 LINQ 表达式节点类型“ArrayIndex”。

    错误原因: bool res1 = S_ROLE_MENU_PURVIEWCODE_Manage.Delete(c => c.MPC_CODE == strs[0]); linq不能写strs[ ...

  10. C#调用默认浏览器打开网页的几种方法

    private void button1_Click(object sender, EventArgs e) { //从注册表中读取默认浏览器可执行文件路径 RegistryKey key = Reg ...