【问题标题】:I can't understand how the time complexity of following c++ code is calculated?我不明白如何计算以下 c++ 代码的时间复杂度?
【发布时间】:2021-11-12 19:41:23
【问题描述】:

以下代码使用 C++ STL 集打印两个未排序数组的并集。
我知道在集合中插入元素的时间复杂度是 O(log N),其中 N 是集合的大小。
此代码来自https://www.geeksforgeeks.org/find-union-and-intersection-of-two-unsorted-arrays/

// C++ program for the union of two arrays using Set
#include <bits/stdc++.h>
using namespace std;
void getUnion(int a[], int n, int b[], int m)
{
 
    // Defining set container s
    set<int> s;

    // Inserting array elements in s
    for (int i = 0; i < n; i++)
      s.insert(a[i]);

    for (int i = 0; i < m; i++)
      s.insert(b[i]);
    cout << "Number of elements after union operation: " << s.size() << endl;
    cout << "The union set of both arrays is :" << endl;
    for (auto itr = s.begin(); itr != s.end(); itr++)
        cout << *itr
             << " "; // s will contain only distinct
                 // elements from array a and b
}

// Driver Code
int main()
{
    int a[9] = { 1, 2, 5, 6, 2, 3, 5, 7, 3 };
    int b[10] = { 2, 4, 5, 6, 8, 9, 4, 6, 5, 4 };

    getUnion(a, 9, b, 10);
}

时间复杂度:O(m * log(m) + n * log(n))
请解释一下上述时间复杂度是如何计算的。

【问题讨论】:

    标签: c++ data-structures stl set


    【解决方案1】:

    在集合中插入一个新元素是对数时间(在你的情况下是 O(log n)O(log m) ),所以总时间复杂度是 O(m * log(m) + n * log(n))

    这里是a link,你可以参考。

    【讨论】:

      【解决方案2】:

      在 C++ 中,set 在内部使用自平衡二叉搜索树 (BST) 实现。这意味着每次将新元素插入set 时,它必须在内部检查该新元素在 BST 中的正确插入位置,然后重新平衡该 BST。插入新元素并执行 BST 重新平衡的操作大约需要 O(log(n)) 时间,其中 n 是 BST 中的元素数量。


      下面的代码sn-p运行n次,每个insert操作在最坏情况下的时间复杂度为O(log(n)),因此下面这段代码的时间复杂度为O(n * log(n))

          for (int i = 0; i < n; i++)
            s.insert(a[i]);
      

      现在,上面的代码 sn-p 执行后,在最坏的情况下,集合将有n 元素(如果int a[] 中的所有n 元素都是唯一的)。

      下面提供的下一个代码 sn-p 运行 m 次,并且每个 insert 操作在最坏的情况下具有 O(log(n + m)) 时间复杂性(因为在此之前的 set 中可能已经有 n 元素下面的循环开始),因此下面这段代码的时间复杂度是O(m * log(m + n))

          for (int i = 0; i < m; i++)
            s.insert(b[i]);
      

      下面的最后一个 for 循环在最坏的情况下运行所有​​n + m 元素(如果数组a[] 中的所有n 元素和数组b[] 中的所有m 元素都是唯一的)。因此,下面代码的时间复杂度为O(n + m),因为下面的代码访问了内部BST中的所有n + m元素。

          for (auto itr = s.begin(); itr != s.end(); itr++)
              cout << *itr
                   << " "; // s will contain only distinct
                       // elements from array a and b
      

      以上 3 个代码 sn-ps 都是串行运行的(一个接一个),因此必须添加总时间复杂度才能找到最终的时间复杂度。

      时间复杂度 = O(nlog(n) + mlog(m + n) + (m + n))

      在上述所有 3 项中,nlog(n)mlog(m + n) 项大于 (m + n),因此我们可以省略 (m + n),并将时间复杂度写为 O(nlog(n) + mlog(m + n))


      相关链接-

      【讨论】:

      • 谢谢。现在我完全明白了上面代码的时间复杂度是如何计算的。
      • 很高兴我能帮上忙,@SakshiHalge,请随时将此答案标记为“已接受”。
      • 偏离路线。这个答案对我有帮助。
      猜你喜欢
      • 1970-01-01
      • 2022-01-19
      • 2018-05-28
      • 1970-01-01
      • 2019-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      相关资源
      最近更新 更多