从这个,我们知道要解决两个排序的数组的交叉方法。那么如何获得多个排序数组的交集呢?
基于两个排序数组的答案,我们可以将其应用于多个数组。这是代码
vector<int> intersectionVector(vector<vector<int> > vectors){ int vec_num = vectors.size(); vector<int> vec_pos(vec_num);// hold the current position for every vector vector<int> inter_vec; // collection of intersection elements while (true){ int max_val = INT_MIN; for (int index = 0; index < vec_num; ++index){ // reach the end of one array, return the intersection collection if (vec_pos[index] == vectors[index].size()){ return inter_vec; } max_val = max(max_val, vectors[index].at(vec_pos[index])); } bool bsame = true; for (int index = 0; index < vec_num; ++index){ while (vectors[index].at(vec_pos[index]) < max_val){ vec_pos[index]++; // advance the position of vector, once less than max value bsame = false; } } // find same element in all vectors if (bsame){ inter_vec.push_back(vectors[0].at(vec_pos[0])); // advance the position of all vectors for (int index = 0; index < vec_num; ++index){ vec_pos[index]++; } } } }
有更好的解决方法吗?
更新1
从这两个主题1和2看来,这Hash set是一种更有效的方法。
Hash set
更新2
为了提高性能,也许min-heap可以使用代替vec_pos我上面的代码。变量max_val保存所有向量的当前最大值。因此,只需将根值与进行比较max_val,如果它们相同,则可以将此元素放入交集列表。
min-heap
vec_pos
max_val
要获得两个排序范围的交集,std::set_intersection可以使用:
std::set_intersection
std::vector<int> intersection (const std::vector<std::vector<int>> &vecs) { auto last_intersection = vecs[0]; std::vector<int> curr_intersection; for (std::size_t i = 1; i < vecs.size(); ++i) { std::set_intersection(last_intersection.begin(), last_intersection.end(), vecs[i].begin(), vecs[i].end(), std::back_inserter(curr_intersection)); std::swap(last_intersection, curr_intersection); curr_intersection.clear(); } return last_intersection; }
这看起来比您的解决方案干净得多,而解决方案过于混乱,无法检查正确性。它还具有最佳的复杂性。
标准库算法set_intersection可以通过使用
set_intersection
最多2·(N1 + N2-1)个比较,其中N1 = std :: distance(first1,last1)和N2 = std :: distance(first2,last2)。
first1等是定义输入范围的迭代器。如果标准库是开源的(例如libstd 或libc ),则可以在标准库的源代码中检查实际的实现。
first1