Union-Find leetcode问题超过时限
Posted
技术标签:
【中文标题】Union-Find leetcode问题超过时限【英文标题】:Union-Find leetcode question exceeding time limit 【发布时间】:2018-09-05 07:12:42 【问题描述】:我正在 leetcode https://leetcode.com/problems/sentence-similarity-ii/description/ 上解决这个问题,该问题涉及实现 union-find 算法来找出两个句子是否相似或没有给出表示相似单词的对列表。我实现了排名联合查找,我跟踪每个子集的大小并将较小的子树连接到较大的子树,但由于某种原因,代码仍然超过时间限制。有人可以指出我做错了什么吗?如何进一步优化。我看到其他公认的解决方案正在使用相同的排名联合查找算法。
代码如下:
string root(map<string, string> dict, string element)
if(dict[element] == element)
return element;
return root(dict, dict[element]);
bool areSentencesSimilarTwo(vector<string>& words1, vector<string>& words2, vector<pair<string, string>> pairs)
if(words1.size() != words2.size()) return false;
std::map<string, string> dict;
std::map<string, int> sizes;
for(auto pair: pairs)
if(dict.find(pair.first) == dict.end())
dict[pair.first] = pair.first;
sizes[pair.first] = 1;
if(dict.find(pair.second) == dict.end())
dict[pair.second] = pair.second;
sizes[pair.second] = 1;
auto firstRoot = root(dict, pair.first);
auto secondRoot = root(dict, pair.second);
if(sizes[firstRoot] < sizes[secondRoot])
dict[firstRoot] = secondRoot;
sizes[firstRoot] += sizes[secondRoot];
else
dict[secondRoot] = firstRoot;
sizes[secondRoot] += sizes[firstRoot];
for(int i = 0; i < words1.size(); i++)
if(words1[i] == words2[i])
continue;
else if(root(dict, words1[i]) != root(dict, words2[i]))
return false;
return true;
谢谢!
【问题讨论】:
好吧,如果dict
很大,那么按值传递它(到root
函数)可能不是一个好主意。将其作为 const
引用传递可能会有所帮助。
该死的,我简直不敢相信自己。非常感谢。
【参考方案1】:
就复杂性而言,您的联合发现被打破了。请阅读Wikipedia: Disjoint-set data structure。
为了使 union-find 具有接近 O(1) 的复杂性,它必须使用路径压缩。为此,您的 root
方法必须:
-
通过引用获取
dict
,以便对其进行修改。
对路径上的所有元素进行路径压缩,使它们指向根。
如果不进行压缩,root()
的复杂度将是 O(log N),这可能没问题。但为此,您必须修复它,以便 root()
通过引用而不是通过值获取 dict
。按价值传递 dict
成本为 O(N)。
dict
是std::map
的事实使得任何查询成本为 O(log N),而不是 O(1)。 std::unordered_map
花费 O(1),但实际上对于 N std::map 更快。此外,即使使用std::unordered_map
,散列一个字符串的成本也是 O(len(str))。
如果数据很大,而性能仍然很慢,您可能会从使用pairs
的索引而不是字符串中获得好处,并使用vector<int>
的索引运行union-find。这很容易出错,因为您必须正确处理重复的字符串。
【讨论】:
以上是关于Union-Find leetcode问题超过时限的主要内容,如果未能解决你的问题,请参考以下文章