题意
给定字符串能否由给定字典中的单词拼接而成.
限制:
字符串长度不大于500
字典单词数不大于1000,每个单词长度不大于20
方法
dfs
通过递归,每次匹配字典里所有单词,一旦匹配成功, 从匹配成功的下标递归搜索下一个位置,如果完全匹配了则返回匹配成功.
代码
class Solution {
public:
bool dfs(const string & s,int idx,vector<string> & dic){ // 递归 字符串 下标 字典
if(idx == s.length())return true; // 完成匹配
for(int i = 0;i<dic.size();i++){ // 遍历字典
if(idx+dic[i].length() > s.length())continue;
bool match = true;
for(int j = 0 ; j<dic[i].length();j++){
if(s[idx+j] != dic[i][j]){ // 字符匹配失败
match = false;
break;
}
}
if(match){
bool r = dfs(s,idx+dic[i].length(),dic); // 递归匹配
if(r)return r;
}
}
return false;
}
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string字符串
* @param dic string字符串vector
* @return bool布尔型
*/
bool wordDiv(string s, vector<string>& dic) {
return dfs(s,0,dic);
}
};
复杂度分析
设字符串长度为m
时间复杂度: 最坏情况下,只有递归的最后一层才不匹配,所有为
空间复杂度: 主要消耗在递归深度上,所以空间复杂度为
枚举搜索字符串
如果字符串是由字典中的构成,那么每次匹配掉一部分,如果能完全匹配掉,则表明字符串是能够由字典中的单词构成.
以样例数据 "nowcoder"为例
初始化时, 空字符串为匹配完成
于是对这个位置尝试匹配"now"和"coder"匹配,匹配成功,标记长度为3的字符串匹配成功
当遍历到字符串的长度为三时,再次尝试匹配"now"和"coder",匹配成功,标记长度为8的字符串匹配成功
代码
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string字符串
* @param dic string字符串vector
* @return bool布尔型
*/
bool wordDiv(string s, vector<string>& dic) {
vector<int> ok(s.length()+1,0);
ok[0] = 1; // 空字符串匹配成功
for(int i = 0;i < s.length();i++){
if(!ok[i])continue; // 能匹配到这个位置
for(int j = 0;j < dic.size();j++){ // 尝试每个字典
if(dic[j].length()+i > s.length())continue; // 忽略超长的字符串
bool match = true; // 匹配
for(int k = 0 ;k<dic[j].length();k++){
if(dic[j][k] != s[i+k]) { // 有字符不同
match = false;
break;
}
}
if(match) { // 所有字符相同
ok[i+dic[j].length()] = true;
}
}
}
return ok[s.length()];
}
};
复杂度分析
时间复杂度: 对于每个匹配成功的位置,尝试了所有字典中的字符串,最差情况是都匹配和尝试,所以时间复杂度为
空间复杂度: 空间上主要消耗在字符串保存,和匹配成功的下标记录,所以空间复杂度为