140. 单词拆分||
知识点:记忆化搜索,动态规划
时间:2020年11月1日
题目链接:https://leetcode-cn.com/problems/word-break-ii
题目
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。
说明:
- 分隔时可以重复使用字典中的单词。
- 你可以假设字典中没有重复的单词。
示例 1:
输入:
s = “catsanddog”
wordDict = [“cat”, “cats”, “and”, “sand”, “dog”]
输出:
[
“cats and dog”,
“cat sand dog”
]
示例 2:
输入:
s = “pineapplepenapple”
wordDict = [“apple”, “pen”, “applepen”, “pine”, “pineapple”]
输出:
[
“pine apple pen apple”,
“pineapple pen apple”,
“pine applepen apple”
]
解释: 注意你可以重复使用字典中的单词。
示例 3:
输入:
s = “catsandog”
wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出:
[]
解法
- 把字典放入set集合中方便使用find函数
- 记忆化搜索 保存从index后所有的可能组合
- 如果这个index后可能性 没有计算过
- 如果达到末尾 这个index后面跟着空字符 返回
- 否则,从index开始往后找,找到第一个词,把剩下的放入dfs中
- 回溯答案,这个index的结果为 这个词+后面的index中对应的词 相加
代码
#include <stdio.h>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
class Solution {
public:
unordered_set<string> dict;
unordered_map<int, vector<string>> ans;
vector<string> wordBreak(string s, vector<string>& wordDict) {
dict = unordered_set<string>(wordDict.begin(),wordDict.end());
dfs(s,0);
return ans[0];
}
void dfs(string s,int idx){
if(!ans.count(idx)){
if(idx == s.size()){
ans[idx] = {""};
return;
}
ans[idx] = {};
for(int i = idx+1; i <= s.length() ;i++){
string tmp = s.substr(idx,i - idx);
if(dict.count(tmp)){
dfs(s,i);
//可能存在多种答案
for(int j = 0;j < ans[i].size();j++){
string push_str = tmp;
// 当到达末尾时 ans[i]="" 不需要空格
if(ans[i][j].size())
push_str = push_str+" "+ans[i][j];
ans[idx].push_back(push_str);
}
}
}
}
}
};
int main()
{
string s{"catsanddog"};
vector<string> dict;
dict.push_back("cat");dict.push_back("cats");dict.push_back("and");
dict.push_back("sand");dict.push_back("dog");
Solution sol;
vector<string> ans = sol.wordBreak(s, dict);
for(string x:ans)
cout<<x<<endl;
return 0;
}
今天也是爱zz的一天哦!