题目:

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++;
} }
};

最新文章

  1. 【linux使用】bash shell命令行常用快捷键 (转载)
  2. linux 安装 ArcSDE10.1
  3. Oracle 学习方法
  4. 20145229&amp;20145316《信息安全系统设计基础》实验一 开发环境的熟悉
  5. 学习服务端JavaScript这个有名的Node.js
  6. 【Beta版本】冲刺-Day1
  7. uva 11572 unique snowflakes——yhx
  8. hdu Proud Merchants
  9. MySql 分组排序取时间最大的一条记录
  10. java中的上传下载----ajaxFileUpload+struts2
  11. jvm-监控指令-jps
  12. C语言语法tips(不断更新)
  13. Centos下配置tomcat7的https证书
  14. backpropagation
  15. S-CMS企业建站v3几处SQL注入
  16. 用TreeSet生成不重复自动排序随机数组
  17. 【NIFI】 Apache NiFI 安装及简单的使用
  18. 有关科学计算方面的python解决
  19. Java8学习笔记(四)--接口增强
  20. csv,json格式数据的读写

热门文章

  1. springboot+cxf 开发webservice
  2. Mybatis-Generator自动生成Dao、Model、Mapping等相关映射文件(懒人版)
  3. The value for the useBean class attribute is invalid.
  4. Water Tree(树链剖分+dfs时间戳)
  5. SpringBoot中使用消息中间件Kafka实现Websocket的集群
  6. mac常用软件
  7. Spring框架的配置文件分开管理(了解)
  8. html菜单和课程表
  9. svn回退版本/取消修改
  10. c++编程思想里面的错误(可能c++标准变了,所以以前的东西没有更新)