Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 联合求解的时间复杂性_Algorithm_Time Complexity_Union Find - Fatal编程技术网

Algorithm 联合求解的时间复杂性

Algorithm 联合求解的时间复杂性,algorithm,time-complexity,union-find,Algorithm,Time Complexity,Union Find,以下问题的解决方案的时间复杂度大约是多少?如果我们假设由于路径压缩,对self.find()的每次调用大致分摊到~O(1) 问题陈述: 给定一个列表accounts,每个元素accounts[i]都是一个字符串列表, 其中,第一个元素accounts[i][0]是名称,其余元素accounts[i][0]是名称 元素是代表帐户电子邮件的电子邮件 现在,我们想合并这些帐户。肯定有两个账户 属于同一个人如果有一些电子邮件是共同的 两个账户都有。请注意,即使两个帐户具有相同的名称,它们也 可能属于不同

以下问题的解决方案的时间复杂度大约是多少?如果我们假设由于路径压缩,对self.find()的每次调用大致分摊到~O(1)

问题陈述:

给定一个列表accounts,每个元素accounts[i]都是一个字符串列表, 其中,第一个元素accounts[i][0]是名称,其余元素accounts[i][0]是名称 元素是代表帐户电子邮件的电子邮件

现在,我们想合并这些帐户。肯定有两个账户 属于同一个人如果有一些电子邮件是共同的 两个账户都有。请注意,即使两个帐户具有相同的名称,它们也 可能属于不同的人,因为人们可能有相同的名字。A. 一个人最初可以拥有任意数量的帐户,但其所有帐户 帐户肯定有相同的名称

合并帐户后,按以下方式返回帐户 格式:每个帐户的第一个元素是名称,其余元素是 元素是按排序顺序排列的电子邮件。账户本身也可以 可以按任何顺序返回

示例:输入:accounts=[[“John”,”johnsmith@example.com", "john00@example.com“],[“约翰”,”johnnybravo@example.com“],[“约翰”, "johnsmith@example.com约翰_newyork@example.com“],[“玛丽”, "mary@example.com“]]

输出:[“约翰”,'john00@example.com”“约翰_newyork@example.com', 'johnsmith@example.com“],[“约翰”,”johnnybravo@example.com“],[“玛丽”, "mary@example.com“]]

说明:第一个和第三个约翰和他们是同一个人 有共同的电子邮件“johnsmith@example.com". 第二个是约翰和玛丽 是不同的人,因为没有人使用他们的电子邮件地址 其他账户。例如,我们可以按任何顺序返回这些列表 答案[玛丽],'mary@example.com“],[“约翰”, 'johnnybravo@example.com“],[“约翰”,”john00@example.com', ”“约翰_newyork@example.com', 'johnsmith@example.com“]]仍然是 接受


逐部分检查代码:

for acc in accounts:
    for i in range(1,len(acc)):
        owners[acc[i]] = acc[0]
        parents[acc[i]] = acc[i]
这是O(N),其中N是输入文本的大小,因为算法只访问输入的每个部分一次。请注意,每个文本元素可能具有任意大小,但这需要考虑,因为N是输入文本的大小。
然后:

这也是O(N),因为:

  • self.find(acc[i],父母)
    被认为是由于path而摊销的O(1) 压实
  • 与之前相同-每个输入元素访问一次

  • 下一步:

    循环本身取决于输入文本的大小N。
    add()
    方法对一个集合进行操作,在python中,这个集合被认为是O(1)。总而言之,该块也需要O(N)


    最后:

    for name,emails in merged.items():         
        res = [owners[name]] + sorted(emails)
        results.append(res)
    
    令人惊讶的是,瓶颈就在这里(至少就O表示法而言)。
    电子邮件
    中的元素数为O(N),因为很可能是系统有一个大用户拥有大部分电子邮件。这意味着
    已排序(电子邮件)
    可以取O(N log N)

    排序后创建res的代码部分:

     res = [owners[name]] + <the sort result>
    
    res=[所有者[名称]]+
    
    这只是排序数据大小的线性关系,它小于排序的O(N logn)

    尽管处于循环中,排序的成本加起来并不超过O(N logn),因为O(N logn)的成本假设有一个大用户。只有少数几个大用户

    例如,假设系统中有K个相等的用户。这使得每个用户的排序成本为O(N/K log(N/K))。对于整个系统,这总计为O(N对数(N/K))。如果K是常数,则变为O(N logn)。如果K是N的函数,那么O(nlog(N/K))比O(nlogn)小这不是一个严格的证明,但足以得出为什么它是O(N logn)而不是更糟的基本概念


    结论:算法以O(N logn)复杂度运行,其中N是输入文本的大小

    注意:复杂性计算有一个主要假设,即在Python中,通过长度为L的字符串键访问映射或集合是一个O(L)操作。这通常是正确的,有一个完美的哈希函数,而Python没有

    for acc in accounts:
         p = self.find(acc[1],parents)
          for i in range(1,len(acc)):
                merged[p].add(acc[i])        
    
    for name,emails in merged.items():         
        res = [owners[name]] + sorted(emails)
        results.append(res)
    
     res = [owners[name]] + <the sort result>