在C ++中,映射比堆有什么优势

时间:2019-05-30 06:32:33

标签: c++ dictionary heap

当前,我在数据结构上遇到问题,并且我有一个问题,我必须在数组中找到第k个最大元素。实际的问题在这里: https://www.geeksforgeeks.org/kth-smallestlargest-element-unsorted-array/

我使用堆以两种不同的方式来解决这个问题,第二种是使用map。

我使用地图的解决方案。

   int t;
cin>>t;
while(--t>=0){
int n,k;
cin>>n;
vector<int> A(n);
for(int i=0;i<n;i++){
cin>>A[i];
 }
cin>>k;
map<int,int> m;
for(int i=0;i<n;i++){
    m[A[i]]++;
}
auto it=m.begin();
for(int i=1;i<=k-1;i++){
    it++;
}
cout<<it->first<<endl;

但是我的地图解决方案给出了超过时间限制。根据我的说法,地图解决方案的时间复杂度为(n + klog(n)),与堆解决方案相同。 那么为什么地图解决方案会赋予TLE?

3 个答案:

答案 0 :(得分:0)

没有看到您的堆版本,我猜想映射的分配是造成麻烦的原因。每个节点都需要分配,这意味着有一个锁和一些其他管理。

并且您必须在map数据结构中内部遵循指针,而在堆中通常不是这种情况。

使用大O表示法不会增加任何时间,但实际上每个操作都会使程序运行速度大大降低。

答案 1 :(得分:0)

使用映射的解决方案的时间复杂度为O(k + nlog(n))。每次插入std::map都会花费log(n)时间,而您正在执行'n'插入。单独插入的时间复杂度将花费O(nlog(n))时间。

有关将元素插入std::map的更多信息,请参见http://www.cplusplus.com/reference/map/map/insert/

答案 2 :(得分:0)

对该算法的简单改进是有一个“技巧”: *如果只需要打印“ k”个元素,则只需记住“ k”个最大元素。这样,插入操作就不会超过O(log k)而不是O(log n)。而且k大概比n小得多。

因此,与其将所有内容插入到越来越大的地图中(而且越来越慢-您提到时间限制),不如将其插入地图。更改代码以一次删除地图中的最小元素(map.size()> = k):

    map<int,int> m;
    for(int i = 0; i < n ; i++) {
        m[A[i]]++;
        if(m.size() > k) {           // <<<<<<<<
             m.erase(m.begin())      // <<<<<<<<
        }
    }