Майкл указал мне, что это можно сделать в O(N)
. Вместо сортировки вы можете использовать два массива размера N. Пройдите по одному вектору, чтобы отметить элементы, которые в нем появляются, проделайте то же самое с другим вектором, затем просмотрите эти два массива, чтобы подсчитать элементы, которые появляются в обоих. Все отдельные шаги O(N)
, следовательно, в сумме это также O(N)
:
#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> v1{ 1, 2, 3, 4, 5, 6, 7, 8 };
std::vector<int> v2{ 5, 7, 9, 10 };
auto m1 = std::minmax_element(v1.begin(),v1.end());
auto m2 = std::minmax_element(v2.begin(),v2.end());
auto min = std::max( *m1.first, *m2.first); // we only need to consider the max minimum element
auto max = std::min( *m1.second, *m2.second); // and the min maximum element
auto get_occurence_vector = [min,max](const std::vector<int>& v) {
std::vector<bool> result(max-min+1); // max and min included, hence +1
for (const auto& e : v) {
int t = e - min;
if (t >= 0 && t <= max) result[t] = true;
}
return result;
};
auto occurs_in1 = get_occurence_vector(v1);
auto occurs_in2 = get_occurence_vector(v2);
size_t counter = 0;
for (size_t i = 0;i< occurs_in1.size(); ++i) {
if (occurs_in1[i] && occurs_in2[i]) {
std::cout << i + min << "\n";
++counter;
}
}
std::cout << "count = " << counter;
}
Вывод:
5
7
count = 2
По сути, это компромисс между сложностью во время выполнения и использование памяти. Если диапазон значений в векторах огромен, но их размер невелик, сортировка может быть более эффективной, даже если сложность хуже (помните, что сложность ограничена большим N
).