【word-break-ii】

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:
	void countBreak(string& s, int index, string str,
							vector<int>& dp, unorderd_set<string>& dict, 
							vector<string>& res, int &length)
	{
		string substr;
		for (int len=1; index+len<=length; ++len)
		{
			if (dp[index+len] && dict.find(s.substr(index, len))!=dict.end())
			{
				substr = s.substr(index,len);
				if (index+len>=length)
				{
					res.push_back(str+substr);
				}
				else
				{
					countBreak(s, index+len, str+substr+" ", dp, dict, res, length);
				}
			}
		}
	}
	vector<string> wordBreak(string s, unordered_set<string>& dict)
	{
		int len = s.size();
		vector<string> res;
		if (len<1)
		{
			return res;
		}

		vector<int> dp(len+1, 0);
		dp[0] = 1;

		for (int i=1; i<=len; i++)
		{
			for (int j=i-1; j>=0; --j)
			{
				if (dp[j] && dict.find(s.substr(j, i-j)!=dict.end())
				{
					dp[i] = 1;
				}
			}
		}

		if (dp[len]==0)
		{
			return res;
		}

		countBreak(s, 0, "", dp, dict, res, len);
		return res;
	}
};


注意:在backtracking 的时候不用考虑下标超姐的情况,直接将所有到0的都加入结果就行了,因为我们在建这个路径时,就是从0开始建的,不可能越界。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值