题目链接:https://leetcode.cn/problems/word-break/
题目如下:
//方法一:动态规划,理解递归公式很重要
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> uset(wordDict.begin(),wordDict.end());
//dp[i]:长度为i的字符串,能否用uset中的单词表示
//单词可表示为物品,字符串可表示为背包容量,由于物品无数量限制,所以为完全背包
vector<bool> dp(s.size()+1,false);
dp[0]=true;
for(int i=1;i<=s.size();i++){
for(int j=0;j<i;j++){//此时容量为i
string str=s.substr(j,i-j);//截取区间从i到j的字符串,j是起始位置,i为最大容量
if(uset.find(str)!=uset.end()&&dp[j]) dp[i]=true;//若这个字符串j~i存在,且0~j也存在,则true
}
}
return dp[s.size()];
}
};
//方法二:回溯,会超时,但是用回溯解决切割问题的思想很重要!!!
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
//新get:将vector初始化到unordered_set中,
//目的:可以使用find函数返回一个string在集合中的迭代器
unordered_set<string> uset(wordDict.begin(),wordDict.end());
return backtracking(s,uset,0);
}
bool backtracking(string s,unordered_set<string>& uset,int startIndex){
if(startIndex>=s.size()) return true;
for(int i=startIndex;i<s.size();i++){
string str=s.substr(startIndex,i-startIndex+1);//从i开始切割,切割区间为startIndex~i
if(uset.find(str)!=uset.end()&&backtracking(s,uset,i+1)) return true;
}
return false;
}
};