139. Word Break 以及 140.Word Break II
139. Word Break
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. You may assume the dictionary does not contain duplicate words.
For example, given
s = "leetcode",
dict = ["leet", "code"].
Return true because "leetcode" can be segmented as "leet code".
思路:
定义状态矩阵dp[i]表示0-i能被切割,需要先找到0-(j -1),然后j -i 这个区间是否是字典里面的,这样找。思路就是序列性动态规划,事件复杂度是n^2.
注意本题的初始化方法,需要从0开始进行查找符合条件的字典字符串,要找到从0位置开始的所有符合条件的字符串,比如go,goal,goals。
class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        if(s.size() == ){
            return false;
        }
        if(wordDict.size() == ){
            return ;
        }
        int n = s.size();
        vector<bool> dp(n,false);
        //hashset
        unordered_set<string> wordSet;
        for(int i = ;i < wordDict.size();++i){
            wordSet.insert(wordDict[i]);
        }
        //find first true
        int ix = ;
        for(ix = ;ix < n;++ix){
            if(wordSet.find(s.substr(,ix + )) != wordSet.end()){
                dp[ix] = true;
                //break;
            }
        }
        // if(ix == n){
        //     return dp[ix - 1];
        // }开始这里没注释,直接每次退出循环ix都等于n,总是出错,因为是原来break掉,才有这句
        //funciton
        for(int i = ;i < n;++i){
            for(int j = ;j <= i;++j){
                if((dp[j - ] == true) && (wordSet.find(s.substr(j,i - j + )) != wordSet.end())){
                    dp[i] = true;
                }
            }
        }
        return dp[n - ];
    }
};
Word breakII需要找出所有符合条件的分割字符串,并且输出。首先考虑DFS模板,这里的巧妙之处就是start取代了j这个变量,但是复杂度还是平方级别。不熟悉的是string的append,insert,erase(pos,arg),记住是包含pos位置的。参考:水中的鱼
class Solution {
public:
    void helper(unordered_set<string> &wordSet,vector<string> &res,string &s,string &tmp,int start){
        if(start == s.size()){
            res.push_back(tmp.substr(,tmp.size() - ));
        }
        for(int i = start;i < s.size();++i){
            string sub = s.substr(start,i - start + );
            if( wordSet.find(sub) == wordSet.end()){
                continue;
            }
            tmp.append(sub).append(" ");//只有每步满足条件之后才开始位置为该步的下一步
            helper(wordSet,res,s,tmp,i + );
            tmp.erase(tmp.size() - sub.size() - );
        }
    }
    vector<string> wordBreak(string s, vector<string>& wordDict) {
        if(s.size() == ){
            return {};
        }
        if(wordDict.size() == ){
             return {};
        }
        vector<string> res;
        unordered_set<string> wordSet;
        for(string tmp : wordDict){
            wordSet.insert(tmp);
        }
        string tmp;
        helper(wordSet,res,s,tmp,);
        return res;
    }
};
这样有很多重复计算,需要引入一个isOK矩阵,记录之前访问的结果,如果在之前i这个位置已经切割了一次,并且没有找到结果,那么就是false,下次不需要再访问了。这里首先都初始化为true。
int oldSize = res.size();
helper(wordSet,res,s,tmp,i + ,isOk);
if(oldSize == res.size()){
isOk[i] = false;
}
这里理解起来比较困难,记住每次经过helper函数应该是有一个结果压入res中的,但是前后size一样大,所以从i这个元素切割没有的得到结果,那下次切割到这个i的时候,就不需要再计算了,直接跳过。
class Solution {
public:
    void helper(unordered_set<string> &wordSet,vector<string> &res,string &s,string &tmp,int start,vector<bool> &isOk){
        if(start == s.size()){
            res.push_back(tmp.substr(,tmp.size() - ));
        }
        for(int i = start;i < s.size();++i){
            string sub = s.substr(start,i - start + );
            if((isOk[i] == false) || wordSet.find(sub) == wordSet.end()){
                continue;
            }
            tmp.append(sub).append(" ");//只有每步满足条件之后才开始位置为该步的下一步
            int oldSize = res.size();
            helper(wordSet,res,s,tmp,i + ,isOk);
            if(oldSize == res.size()){
                isOk[i] = false;
            }
            tmp.erase(tmp.size() - sub.size() - );
        }
    }
    vector<string> wordBreak(string s, vector<string>& wordDict) {
        if(s.size() == ){
            return {};
        }
        if(wordDict.size() == ){
             return {};
        }
        vector<string> res;
        unordered_set<string> wordSet;
        for(string tmp : wordDict){
            wordSet.insert(tmp);
        }
        string tmp;
        vector<bool> isOk(s.size(),true);//代表从i位置分割是否能得到一个结果
        //isOk[0] = false;
        helper(wordSet,res,s,tmp,,isOk);
        return res;
    }
};
139. Word Break 以及 140.Word Break II的更多相关文章
- leetcode 139. Word Break 、140. Word Break II
		
139. Word Break 字符串能否通过划分成词典中的一个或多个单词. 使用动态规划,dp[i]表示当前以第i个位置(在字符串中实际上是i-1)结尾的字符串能否划分成词典中的单词. j表示的是以 ...
 - 140. Word Break II(hard)
		
欢迎fork and star:Nowcoder-Repository-github 140. Word Break II 题目: Given a non-empty string s and a d ...
 - [LeetCode] 140. Word Break II 单词拆分II
		
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add space ...
 - LeetCode笔记:140. Word Break II
		
题目描述 给定一个非空的字符串s,一个非空的字符串list作为字典.通过在s中添加空格可以将s变为由list中的word表示的句子,要求返回所有可能组成的句子.设定list中的word不重复,且每一个 ...
 - leetcode 79. Word Search 、212. Word Search II
		
https://www.cnblogs.com/grandyang/p/4332313.html 在一个矩阵中能不能找到string的一条路径 这个题使用的是dfs.但这个题与number of is ...
 - C#操作Word (1)Word对象模型
		
Word对象模型 (.Net Perspective) 本文主要针对在Visual Studio中使用C# 开发关于Word的应用程序 来源:Understandingthe Word Object ...
 - Java实现 LeetCode 140 单词拆分 II(二)
		
140. 单词拆分 II 给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中.返回所有这些可能的句子. 说明: 分 ...
 - Java实现 LeetCode 140 单词拆分II
		
class Solution { public List<String> wordBreak(String s, List<String> wordDict) { List&l ...
 - C#中操作Word(1)—— word对象模型介绍
		
一.开发环境布置 C#中添加对Word的支持,只需添加对Microsoft.Office.Interop.Word的命名空间,如下图所示,右键点击“引用”,在弹出的“添加引用”对话框中选中COM标签页 ...
 
随机推荐
- 1146. Snapshot Array
			
Implement a SnapshotArray that supports the following interface: SnapshotArray(int length) initializ ...
 - UIKeyWindow的设置
			
新建一个纯代码iOS项目,需要对AppDelegate文件和项目的Info.plist文件做一番配置. 第一步:将Info.plist中的下面两项的value删除掉(保留空字符串),如下图 第二步:在 ...
 - 发送邮件#Python
			
import yagmailusername='11@qq.com' #发件人邮箱qq='zhezlqiggd' #授权码,QQ邮箱可在设置账户获得mail_server='smtp.qq.com' ...
 - linux 基本命令学习总结
			
1. linux的目录结构 (linux核心:一切皆文件) 目录结构解释 (主要的有 /etc /home /mnt /opt /usr /tmp) 相对路径和绝对路径的区别 绝对路径 ...
 - 135、Java中的静态块,构造方法和构造块
			
01.代码如下: package TIANPAN; class Book { static String msg; // static属性,暂不封装 public Book() { // 构造方法 S ...
 - java连接sql server 2008
			
请先确保已经设置好了sa,如果不是,可以参照下面链接修改http://jingyan.baidu.com/article/8cdccae9452b3c315513cd52.html 然后重启数据库,重 ...
 - Eclipse配置maven和新建maven工程
			
1 安装配置Maven 1.1 下载Maven 从Apache网站 http://maven.apache.org/ 下载并且解压缩安装Apache Maven. Maven下载地址: http:/ ...
 - 2020.2.19   restful的学习
			
restful Api 设计要素 3-8 如何设计Restful Api 资源路径(url),HTTP动词,过滤信息(做分页),状态码,错误处理,返回结果 3-9 初始化运行参数 3-10 ...
 - ClientDataSet.locate报错问题
			
数据集循环之后如果使用locate定位,需要首先将数据集first
 - C. Maximum Median  二分
			
C. Maximum Median 题意: 给定一个数组,可每次可以选择一个数加1,共执行k次,问执行k次操作之后这个数组的中位数最大是多少? 题解:首先对n个数进行排序,我们只对大于中位数a[n/2 ...