给出了一个单词列表,并给出了一个更大的字符串,给出了如何找到该字符串是否是较小字符串的排列。
eg- s= badactorgoodacting dict[]={'actor','bad','act','good'] FALSE
eg- s= badactorgoodacting dict[]={'actor','bad','acting','good'] TRUE
较小的单词本身不需要置换。问题是我们是否可以找到较小字符串的顺序,这样如果按顺序连接它会给出更大的字符串
还有一个限制 - 来自dict[]
的某些字词也可能会遗留在未使用的
以下给出了复杂度O(n2)。有没有其他方法可以做到这一点..以便提高复杂性或提高效率?主要是在Java中。在此先感谢!
bool strPermuteFrom(unordered_set<string> &dict, string &str, int pos)
{
if(pos >= str.size())
return true;
if(dict.size() == 0)
return false;
for(int j = pos; j < str.size(); j++){
string w = str.substr(pos, j - pos + 1);
if(dict.find(w) != dict.end()){
dict.erase(w);
int status = strPermuteFrom(dict, str, j+1);
dict.insert(w);
if(status){
if(pos > 0) str.insert(pos, " ");
return status;
}
}
}
return false;
}
bool strPermute(unordered_set<string> &dict, string &str)
{
return strPermuteFrom(dict, str, 0);
}
答案 0 :(得分:1)
您提供的代码示例并没有充分利用unordered_set
(相当于Java HashSet
的属性);每个查找都是O(1)
,但它必须执行许多查找(对于每个可能的前缀,对于字符串的整个长度)。正在排序的std::set
(Java TreeSet
)允许您在单个O(log n)
查找中找到给定点的所有可能前缀(然后从该点开始扫描,直到您不再处理可能的前缀),而不是在每个递归步骤中查找stringlength
O(1)
。
因此,此代码正在执行O(stringlength * dictsize^2)
工作,使用有序集合结构应将其减少到O(dictsize log dictsize)
工作。字符串长度无关紧要,因为您不再查找前缀;你在每个递归步骤中查找剩余的字符串一次,并且因为它是有序的,匹配的前缀将在整个字符串之前排序,不需要检查单个子字符串。从技术上讲,回溯仍然是必要的(处理dict中的单词是dict中另一个单词的前缀的情况,例如act
和acting
),但除此之外,你' d永远不需要回溯;对于每个递归步骤,您只需要一次点击,因此您只需要执行dictsize查找,每次查找都会花费log dictsize
。