Следующий код печатает объединение двух несортированных массивов с использованием набора C ++ STL.
Я знаю, что сложность вставки элемента в набор составляет O (log N), где N - размер набора.
Этот код взят с сайта https: //www.geeksforgeeks .org / найти-объединение-и-пересечение-двух-несортированных-массивов /.

// 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)) .
Пожалуйста, объясните, как рассчитывается указанная выше временная сложность.

0
Sakshi Halge 18 Сен 2021 в 07:52

2 ответа

Лучший ответ

В C ++ set внутренне реализован с использованием самобалансирующегося двоичного дерева поиска (BST). Это означает, что каждый раз, когда новый элемент вставляется в set, он должен внутренне проверять правильное место вставки этого нового элемента в BST, а затем повторно балансировать этот BST. Эта операция вставки нового элемента и выполнения перебалансировки BST занимает приблизительно O(log(n)) времени, где n - количество элементов в BST.


Приведенный ниже фрагмент кода выполняется n раз, и каждая операция insert имеет O(log(n)) временную сложность в худшем случае, следовательно, временная сложность приведенного ниже фрагмента кода равна O(n * log(n)).

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

Теперь, после выполнения приведенного выше фрагмента кода, набор будет иметь элементы n в худшем случае (если все элементы n в int a[] уникальны).

Следующий фрагмент кода, представленный ниже, выполняется m раз, и каждая операция insert имеет O(log(n + m)) временную сложность в худшем случае (поскольку в n уже могут быть элементы в set перед запуском этого цикла ниже), следовательно, временная сложность приведенного ниже фрагмента кода равна O(m * log(m + n)).

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

Последний цикл for ниже выполняется для всех элементов n + m в худшем случае (если все элементы n в массиве a[] и все элементы m в массиве b[]} уникальны). Следовательно, временная сложность приведенного ниже кода равна O(n + m), потому что приведенный ниже код посещает все элементы n + m во внутреннем BST.

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

Все 3 приведенных выше фрагмента кода выполняются последовательно (один за другим), поэтому необходимо добавить общую временную сложность, чтобы найти окончательную временную сложность.

Сложность времени = O(nlog(n) + mlog(m + n) + (m + n))

Из всех трех указанных выше терминов, термины nlog(n) и mlog(m + n) больше, чем (m + n), поэтому мы можем опустить (m + n) и записать временную сложность как O(nlog(n) + mlog(m + n)).


Соответствующие ссылки -

0
Dhruv Saraswat 18 Сен 2021 в 06:20

Вставка нового элемента в набор выполняется за логарифмическое время (в вашем случае O (log n) и O (log m)), поэтому общая временная сложность составляет O (m * log (m) + n * log (n)). Вот ссылка, на которую можно сослаться.

0
nikhilsahu 18 Сен 2021 в 05:47