The provided code has O(N^2) worst-case time complexity. You can use std::unordered_map to achieve O(N) complexity, which is optimal because reading the input takes O(n) time.
For future questions, I would suggest providing the entire program and some test cases. This makes it easier to understand the types of variables and provide suggestions that are useful.
Below is an implementation with std::unordered_map and testing / benchmarking.
#include <vector>
#include <unordered_map>
#include <iostream> // for printing
#include <cassert> // for testing
#include <chrono> // for benchmarking
using std::vector;
typedef std::chrono::high_resolution_clock::time_point time_point;
// provided code
vector<int> filter_triples1(const vector<int> &v)
{
vector<int> a(v);
int N = a.size();
for (int i = N - 1; i >= 0; i--)
{
size_t c = 0;
bool flag = false;
for (int j = N - 1; j >= 0 && c < 3 && !flag; j--)
{
c += a[i] == a[j];
if (j > i)
flag = a[i] == a[j];
}
if (c != 3 && !flag)
{
for (int j = i; j < N - 1; j++)
a[j] = a[j + 1];
N--;
}
}
a.resize(N);
return a;
}
// returns a copy of v containing only the
// elements that appear at least 3 times
vector<int> filter_triples2(const vector<int> &v)
{
// counts[x] is the number of times x appears
std::unordered_map<int, int> counts;
for (const auto &x : v)
++counts[x];
vector<int> result;
for (const auto &x : v)
if (counts[x] >= 3)
result.push_back(x);
return result;
}
// returns the time right now
time_point get_now()
{
return std::chrono::high_resolution_clock::now();
}
int main()
{
// testing
vector<vector<int>> tests = {
{},
{1},
{1, 1, 1},
{1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3}
};
for (const auto &test : tests)
{
vector<int> answer1 = filter_triples1(test);
vector<int> answer2 = filter_triples2(test);
assert(answer1 == answer2);
}
// benchmarking
vector<int> test;
for (int i = 0; i < 100000; ++i)
test.push_back(i);
time_point start1 = get_now();
vector<int> answer1 = filter_triples1(test);
std::chrono::duration<double> diff1 = get_now() - start1;
time_point start2 = get_now();
vector<int> answer2 = filter_triples2(test);
std::chrono::duration<double> diff2 = get_now() - start2;
std::cout << "time1: " << diff1.count();
std::cout << "\ntime2: " << diff2.count();
assert(answer1 == answer2);
return 0;
}
Here is the output:
time1: 40.8914
time2: 0.116645
This shows a >100x speedup for N = 100000.