题目:

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

Return all such possible sentences.

For example, given
s = "catsanddog",
dict = ["cat", "cats", "and", "sand", "dog"].

A solution is ["cats and dog", "cat sand dog"].

解题思路:

这道题是上一道题Word Break升级版,难度更大些,需要用DP+DFS解决

这里采用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。

因为本题需要重构结果,所以必须要有一个数据结构来保存每段长度的切割方案,这里我用unordered_map<int, vector<int> >进行保存,key为字符长度,vector保存该key对应的切割方案。

如何求得unordered_map<int, vector<int> >中的值呢?那就应该利用求解dp[i]时,每当有一种切割方案使得dp[i]为true时,将其对应的切割位置存放到i对应的vector中,待之后用于结果重构。

unordered_map<int, vector<int> >求得后,接下来是采用DFS算法进行结果重构,如代码执行结果图,当长度为10时,有一种切割方案,即在长度为7的位置进行切割,然后长度为7的切割方案又有两种3和4,长度为3和4时,切割方案都为0,所以采用DFS时,遍历顺序为7,3,0然后获得一种结果,之后回溯到7,4,因为4的切割方案为0,所以为7,4,0,又是一种结果。

实现代码:

#include <iostream>
#include <string>
#include <vector>
#include <unordered_set>
#include <unordered_map>
using namespace std; /*
Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word. Return all such possible sentences. For example, given
s = "catsanddog",
dict = ["cat", "cats", "and", "sand", "dog"]. A solution is ["cats and dog", "cat sand dog"].
*/
class Solution {
public:
vector<string> wordBreak(string s, unordered_set<string> &dict) {
vector<string> retvec;
if(s.size() == || dict.size() == )
return retvec;
int len = s.size();
vector<bool> dp(len+, false);//保存状态,dp[i]表示前i个字符是否可以进行wordBread
unordered_map<int, vector<int> > hash_map;// 存放使得dp[i]为true的切割方案
dp[] = true;
for(int i = ; i <= len; i++)
{
vector<int> vec;
for(int j = ; j < i; j++)
{
if(dp[j] && dict.count(s.substr(j, i-j)) == )//对前i个字符进行切分时,只要有一种情况为true,则dp[i]=true
{
dp[i] = true;
vec.push_back(j);//放使得dp[i]为true的切割方案
}
}
hash_map[i] = vec;
} for(int k = ; k <= len; k++)
{
vector<int> tvec = hash_map[k];
cout<<k<<":";
vector<int>::iterator iter;
for(iter = tvec.begin(); iter != tvec.end(); ++iter)
{
cout<<*iter<<" ";
}
cout<<endl;
} vector<int> curVec;
getResult(hash_map, s, len, retvec, curVec);
return retvec; } //采用DFS解决
void getResult(unordered_map<int, vector<int> > &hash_map,string s, int len, vector<string> &retvec, vector<int> &curVec)
{
if(len == )
{
string t;
int start = ;
for(int i = curVec.size()-; i >= ; i--)
{
int c = curVec[i];
t += s.substr(start, c-start);
t += " ";
start = c;
}
t += s.substr(curVec[]);
retvec.push_back(t);
return ;
}
vector<int> tvec = hash_map[len];
vector<int>::iterator iter;
for(iter = tvec.begin(); iter != tvec.end(); ++iter)
{
curVec.push_back(*iter);
getResult(hash_map, s, *iter, retvec, curVec);
curVec.pop_back();
} } }; int main(void)
{
string s("catsanddog");
unordered_set<string> dict;
dict.insert("cat");
dict.insert("cats");
dict.insert("and");
dict.insert("sand");
dict.insert("dog"); Solution solution;
vector<string> retvec = solution.wordBreak(s, dict);
vector<string>::iterator iter;
for(iter = retvec.begin(); iter != retvec.end(); ++iter)
cout<<*iter<<endl; return ;
}

执行结果:

LeetCode140:Word Break II的更多相关文章

  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. 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 ...

  3. 【LeetCode】140. Word Break II

    Word Break II Given a string s and a dictionary of words dict, add spaces in s to construct a senten ...

  4. LeetCode: Word Break II 解题报告

    Word Break II Given a string s and a dictionary of words dict, add spaces in s to construct a senten ...

  5. [Leetcode Week9]Word Break II

    Word Break II 题解 题目来源:https://leetcode.com/problems/word-break-ii/description/ Description Given a n ...

  6. 【Word Break II】cpp

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

  7. 140. Word Break II(hard)

    欢迎fork and star:Nowcoder-Repository-github 140. Word Break II 题目: Given a non-empty string s and a d ...

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

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

  9. 【leetcode】Word Break II

    Word Break II Given a string s and a dictionary of words dict, add spaces in s to construct a senten ...

随机推荐

  1. Dubbo简单理解

    Dubbo 致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,Dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有Dubbo这样 ...

  2. 重哈希 · rehashing

    [抄题]: [思维问题]: [一句话思路]: [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入): [画图]: newindex = (hashTable[ ...

  3. Spring boot starter pom的依赖关系说明

    Spring Boot 通过starter依赖为项目的依赖管理提供帮助.starter依赖起始就是特殊的maven依赖,利用了传递依赖解析,把常用库聚合在一起,组成了几个为特定功能而定制的依赖. sp ...

  4. memcache缓存失效

    缓存过期 memcached在处理过期的缓存项时,采用懒惰模式处理方法. 缓存项过期,不会立即删除,直到对该缓存项执行了get操作,才会删除过期缓存. > set key 0 10 > t ...

  5. C#开发中常用加密解密方法解析

    一.MD5加密算法 我想这是大家都常听过的算法,可能也用的比较多.那么什么是MD5算法呢?MD5全称是message-digest algorithm 5,简单的说就是单向的加密,即是说无法根据密文推 ...

  6. Spring框架之CGLIB的代理技术(代码了解)

    1.引入CBLIB的开发包 * 如果想使用CGLIB的技术来生成代理对象,那么需要引入CGLIB的开发的jar包,在Spring框架核心包中已经引入了CGLIB的开发包了.所以直接引入Spring核心 ...

  7. centos一键安装lnmp成功后无法访问ip(解决办法)

    自己搞了个服务器 (我的服务器网络类型是 专有网络)如下图点击 配置规则 进入到 进.出端口规则配置 点击添加安全组规则 如图所配置  添加完成后 就如下面所示 (配置完成后 通过ip就已经可以访问了 ...

  8. 使用JMX监控Storm的nimbus、supervisor、woker

    可以通过在storm.yaml中增加如下样例的配置, 启动JMX来监控storm的各个角色. 其中对于Worker的监控,因为一个节点上可以有多个work,为了防止端口号重复导致启动失败,所以用动态代 ...

  9. AMD、CMD、UMD 模块的写法

    简介 最近几年,我们可以选择的Javascript组件的生态系统一直在稳步增长.虽然陡增的选择范围是极好的,但当组件混合匹配使用时就会出现很尴尬的局面.开发新手们会很快发现不是所有组件都能彼此“和平相 ...

  10. proc demo

    源文件test.pc #include <stdio.h> #include <string.h> #include <stdlib.h> #include &qu ...