题目来源
给一个字符串数组,求这数组里面能由至少两个其他的字符串组成的字符串。
我想到了先把所有字符串都搞进哈希表,然后进行遍历,但是没想到怎么在遍历过程中判断这个字符串是不是我们要找的字符串。
然后发现这是一道DP题,dp[i]
表示前i
个字符能够由其它字符串组成。
dp[j] = 1 if dp[j-i] = 1 and s[i:j] belong to array
代码如下:
class Solution {
public:
vector<string> findAllConcatenatedWordsInADict(vector<string>& words) {
unordered_set<string> s(words.begin(), words.end());
vector<string> res;
for (auto word : words) {
int n = word.size();
vector<int> dp(n+1, 0);
dp[0] = 1;
for (int i=0; i<n; i++) {
if (dp[i] == 0) continue;
for (int j=i+1; j<=n; j++) {
if (j-i<n && s.count(word.substr(i, j-i)))
dp[j] = 1;
}
if (dp[n] == 1) {
res.push_back(word);
break;
}
}
}
return res;
}
};
然后看了下讨论区,也有用回溯的方法,会比DP要快一些,代码如下:
class Solution {
public:
vector<string> findAllConcatenatedWordsInADict(vector<string>& words) {
unordered_set<string> dic(words.begin(), words.end());
vector<string> res;
for (int i = 0; i < words.size(); i++) {
if (isConcatenated(words[i], dic, false)) res.push_back(words[i]);
}
return res;
}
bool isConcatenated(string word, unordered_set<string>& dic, bool isSubstr) {
if (word.empty()) return isSubstr;
if (isSubstr && dic.count(word)) return true;
for (int len=1;len<word.size();len++) {
if (dic.count(word.substr(0, len)) && isConcatenated(word.substr(len), dic, true)) {
return true;
}
}
return false;
}
};