[LeetCode]Word Break 特里
意甲冠军:推断字符串给定的字符串是否构成词典。
来推断目标字符串相匹配整个字典。我们需要来推断目标字符串的每个前缀开始的下一场比赛,这需要匹配目标字符串的成功,所有前缀的枚举。
class TrieNode{//from http://www.cnblogs.com/x1957/p/3492926.html
public:
    TrieNode* ch[26];//char指针数组
    bool isWord;
    TrieNode():isWord(false){
        memset(ch,0,sizeof(TrieNode*)*26);
    }
    void insert(const string& ps){
        TrieNode*q=this;
        int id;
        const char* p=ps.c_str();
        while(*p){
            id=p[0]-'a';
            if(NULL==q->ch[id])
                q->ch[id]=new TrieNode();
            q=q->ch[id];
            p++;
        }
        q->isWord=true;//是一个前缀
    }
    ~TrieNode(){
        for(int i=0;i<26;++i)
            delete ch[i];
    }
};
class Solution {
public:
    bool *find;
    TrieNode *root;
    void match(string &s,int st,int ed){
        TrieNode*p=root;
        for(int i=st;i<ed;++i){
            if(p->ch[s[i]-'a']){
                p=p->ch[s[i]-'a'];
                if(p->isWord)find[i]=true;
            }
            else break;
        }
    }
    bool wordBreak(string s, unordered_set<string> &dict) {
        int i,n=s.size();
        unordered_set<string>::iterator bg,ed;
        root=new TrieNode();
        for(bg=dict.begin(),ed=dict.end();bg!=ed;bg++){
            root->insert(*bg);
        }
        find=new bool[n];
        memset(find,0,sizeof(bool)*n);
        //先匹配前缀
        match(s,0,n);
        //再从全部匹配的单词開始接下去匹配
        for(i=0;i<n&&find[n-1]==false;++i)
            if(find[i])
                match(s,i+1,n);
        bool ans=find[n-1];
        delete[]find;
        delete root;
        return ans;
    }
};
DP版:
一个串AB可看成两个子串A、B构成。假设A和B都匹配。则AB匹配。用dp[i]表示前缀(0,i)是否匹配,则dp[n]=dp[0,k]&dp[k+1,n],k∈[0,n]。
这里dp[0,k]比較easy求,要推断后缀dp[k+1,n]是否在dict中。除了通过set.find(dp[k+1,n])不知还有什么办法。
bool wordBreak(string s, unordered_set<string> &dict) {
        int i,j,n=s.size();
        bool *dp=new bool[s.size()];
	 	memset(dp,0,sizeof(bool)*n);
		for(i=0;i<n;++i){
			dp[i]=dict.find(s.substr(0,i+1))!=dict.end();
			for(j=0;j<i&&!dp[i];++j){
				dp[i]=(dp[j]&(dict.find(s.substr(j+1,i-j))!=dict.end()));
			}
		}
		bool ans=dp[n-1];
		delete[]dp;
		return ans;
    }
问题2:输出全部匹配的字符串 https://oj.leetcode.com/problems/word-break-ii/
方法:在每一个匹配的时候,针对每一个匹配的子串,记录能够匹配到该位置的子串起始位置。这样串中的一个字符就可能有多种匹配结果。
仅仅要由后往前回溯输出全部可能就可以。
class TrieNode{
public:
	TrieNode*child[26];
	bool isWord;
	TrieNode():isWord(false){
		memset(child,0,sizeof(TrieNode*)*26);
	}
	void insert(const string &str){
		int n=str.size(),i,id;
		TrieNode*p=this;
		for(i=0;i<n;++i){
			id= str[i]-'a';
			if(!p->child[id]) {
				p->child[id]=new TrieNode();
			}
			p=p->child[id];
		}
		p->isWord=true;
	}
	~TrieNode(){
		for(int i=0;i<26;++i){
			delete child[i];
			child[i]=NULL;
		}
	}
};
class Solution{
public:
	TrieNode*root;
	bool *find;
	vector<string>ans;
	void match(string &str,int st,int ed,vector<set<int> >&pos){
		int i,id;
		TrieNode*p=root;
		for(i=st;i<=ed;++i){
			id=str[i]-'a';
			if(p->child[id]){
				p=p->child[id];
				if(p->isWord){
					find[i]=true;
					pos[i].insert(st);
				}
			}
			else break;
		}
	}
	void dfs(string &str,int id,vector<set<int> >&pos,int *b,int len){
		if(id<0){
			string tmp;
			for(int i=len-1;i>0;--i){
				if(i<len-1)tmp+=" ";
				tmp+=str.substr(b[i],b[i-1]-b[i]);
			}
			ans.push_back(tmp);
			return;
		}
		set<int>::iterator bg=pos[id].begin(),ed=pos[id].end();
		for(;bg!=ed;bg++){
			b[len]=*bg;
			dfs(str,b[len]-1,pos,b,len+1);
		}
	}
	vector<string>wordBreak(string s, unordered_set<string>&dict){
		if(s.size()==0){
			return vector<string>();
		}
		unordered_set<string>::iterator bg,ed;
		root=new TrieNode();
		int n=s.size(),i;
		for(bg=dict.begin(),ed=dict.end();bg!=ed;bg++){
			root->insert(*bg);
		}
		find=new bool[n];
		vector<set<int> >pos(n);
		int *b=new int[n+2];
		memset(find,0,sizeof(bool)*n);
		match(s,0,n-1,pos);
		for(i=0;i<n;++i){
			if(find[i])
				match(s,i+1,n-1,pos);
		}
		int x=0;
	//	cout<<pos[6].size();
		if(find[n-1]){
			b[x++]=n;
			dfs(s,n-1,pos,b,x);
		}
		delete[] find;
		delete[] b;
		return ans;
	}
};
版权声明:本文博主原创文章,博客,未经同意不得转载。
[LeetCode]Word Break 特里的更多相关文章
- [LeetCode] Word Break II 拆分词句之二
		Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each ... 
- LeetCode:Word Break II(DP)
		题目地址:请戳我 这一题在leetcode前面一道题word break 的基础上用数组保存前驱路径,然后在前驱路径上用DFS可以构造所有解.但是要注意的是动态规划中要去掉前一道题的一些约束条件(具体 ... 
- LeetCode Word Break II
		原题链接在这里:https://leetcode.com/problems/word-break-ii/ 题目: Given a string s and a dictionary of words ... 
- [leetcode]Word Break II @ Python
		原题地址:https://oj.leetcode.com/problems/word-break-ii/ 题意: Given a string s and a dictionary of words ... 
- 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 ... 
- LeetCode ||& Word Break && Word Break II(转)——动态规划
		一. Given a string s and a dictionary of words dict, determine if s can be segmented into a space-sep ... 
- [LeetCode] Word Break II 解题思路
		Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each ... 
- [Leetcode] word break ii拆分词语
		Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each ... 
- LeetCode: Word Break I && II
		I title: https://leetcode.com/problems/word-break/ Given a string s and a dictionary of words dict, ... 
随机推荐
- 高级Java工程师必备 ----- 深入分析 Java IO (三)
			概述 Java IO即Java 输入输出系统.不管我们编写何种应用,都难免和各种输入输出相关的媒介打交道,其实和媒介进行IO的过程是十分复杂的,这要考虑的因素特别多,比如我们要考虑和哪种媒介进行IO( ... 
- WCF REST 基础教程
			概述 Representational State Transfer(REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格. 因此REST是设计风格而不是标准,R ... 
- HDU 1405 The Last Practice  数学水题
			http://acm.hdu.edu.cn/showproblem.php?pid=1405 题目大意: 给你一个数,让你分解素因子,输出它的各次幂. 如60 输出:2 2 3 1 5 1 (60=2 ... 
- Tomcat请求处理过程(Tomcat源代码解析五)
			watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ... 
- iOS进阶路线以及进阶书籍
			第一,熟悉ARC机制:首先要了解ARC的前世今生.假设了解不清楚会导致两种可能,1,一个对象的引用莫名奇异为空.或失效了.这个一般都能在开发阶段及时发现,由于会导致应用异常.2.导致内存溢出:不了解A ... 
- [SQL]远程使用PostgreSQL Studio可视化查看PostgreSQL数据库
			1.下载 前往官网地址下载最新的PostgreSQL Studio,我下载的是 pgstudio_1.2-bin .zip,由于我的电脑里面没有tomcat. 假设电脑里有配置好tomcat,能够下载 ... 
- 【hdu 1846】Brave Game
			Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ... 
- Erlang 聊天室程序
			Erlang 聊天室程序( 一) Erlang 聊天室程序(二) 客户端的退出 Erlang 聊天室程序(三) 数据交换格式---json的decode Erlang 聊天室程序(四) 数据交换格式- ... 
- 移动端iPhone系列适配问题的一些坑
			完成移动端的开发项目之后,发现谷歌自带的调试器似乎没有什么太大的作用,整天借同事的苹果手机测bug,尽管同事不厌其烦,但还是觉得这iPhone系列适配问题适配到想逃逃逃,好在项目已经顺利完成,测试通过 ... 
- try catch finally中的return
			try catch 中finally语句总是可以执行的,不管try中是否含有return语句 public class TestReturn { public static void main(Str ... 
