我有一对整数对的向量,看起来有点像:
(0, 1)
(1, 9)
(2, 3)
(6, 1)
(4, 0)
我想从中提取唯一元素,结果如下:
0, 1, 9, 2, 3, 6, 4
(基本上只是所有数字都没有重复)
目前我这样做:
std::vector<int> getElements(std::vector<std::pair<int, int>> S) {
std::vector<int> V;
for (std::vector<std::pair<int, int>>::iterator i = S.begin(); i != S.end(); i++) {
if (std::find(V.begin(), V.end(), i->first) == V.end()) {
V.push_back(i->first);
}
if (std::find(V.begin(), V.end(), i->second) == V.end()) {
V.push_back(i->second);
}
}
return V;
}
有没有更有效的方法呢?
答案 0 :(得分:6)
您当前的解决方案是O(n^2)
。您可以使用O(1)
将已经看到过的元素的线性扫描缩减为已摊销的std::unordered_set
来存储已经看过的数字;这会将您的运行时间提高到O(n)
。
这是一个改进的算法:
std::vector<int> getElements(std::vector<std::pair<int, int>> S) {
std::unordered_set<int> ss;
std::for_each(S.begin(), S.end(), [&ss](const auto& p) {
ss.insert(p.first);
ss.insert(p.second);
});
return std::vector<int>(ss.begin(), ss.end());
}
查看示例Live On Coliru
答案 1 :(得分:3)
有没有更有效的方法呢?
是的,有。 std::find
对于向量具有O(n)复杂度,因此对每个元素重复它会给出O(n * n)复杂度。
一个简单的替代方法是将每个元素添加到std::set
中。构建集合的复杂性是O(n log n)。
答案 2 :(得分:3)
未测量,但我认为它更快......
#include <iostream>
#include <algorithm>
#include <vector>
std::vector<int> getElements(std::vector<std::pair<int, int>>& S) {
std::vector<int> V;
V.reserve(2*S.size());
for (const auto& i : S) {
V.push_back(i.first);
V.push_back(i.second);
}
std::sort(V.begin(), V.end());
V.erase(std::unique(V.begin(), V.end()), V.end());
return V;
}
int main()
{
std::vector<std::pair<int, int>> v{{0, 1},{1, 9},{2, 3},{6, 1},{4, 0}};
for(const auto& i : getElements(v))
std::cout << i << ' ';
std::cout << '\n';
}