LeetCode/单词拆分
给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
思路:对于是否可行问题考虑用回溯法,递归s串中的下标,同时遍历可选字典数组,进行匹配,匹配失败选择其他项,防止无限递归
当数据规模变大后,回溯法运行超时
回溯法
class Solution {
public:
bool flag = false;
bool wordBreak(string s, vector<string>& wordDict) {
//每个满足条件的单词都应该进行匹配
//判断可行考虑用回溯法
backtrack(s,wordDict,0);
return flag;
}
void backtrack(string s,vector<string>& wordDict,int index){
if(index==s.size()){flag=true;return;}
int start = index;
for(int i=0;i<wordDict.size();i++){
index = compare(s,wordDict[i],index);
if(index==start) continue;
backtrack(s,wordDict,index);
if(flag) return;
index = start;
}
}
int compare(string s,string wordDict,int index){
int start = index;
for(int j=0;j<wordDict.size();j++){
if(index>s.size()-1||s[index]!=wordDict[j]) return start;
index++;
}
return index;
}
};
动态规划
dp[i]表示为前i个字符组成的串匹配成功的可行性
边界条件:dp[0]=true;
状态转移方程:dp[i]=dp[j]&&(j-i字符串在字典中)//j遍历i前面全部位置
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> wordDictSet(wordDict.begin(), wordDict.end());//哈希表判断匹配
vector <bool> dp(s.size() + 1);
dp[0] = true;
for (int i = 1; i <= s.size(); ++i) {//评估前i位字符串是否能匹配成功
for (int j = 0; j < i; ++j) {//判断前j位是否匹配成功,以及j到i之间字符串是否存在匹配项
if (dp[j] && wordDictSet.count(s.substr(j, i - j)) ) {
dp[i] = true;
break;
}
}
}
return dp[s.size()];
}
};