为什么两个看似相同的lower_bound()方法具有不同的处理时间

时间:2016-01-21 11:07:15

标签: algorithm c++11 set multiset

当我解决算法问题时,由于时间问题,我的解决方案无法通过。
但我意识到,通过和我之间的唯一区别是

bag.lower_bound(jewerly[i].first) != bag.end() //passed

lower_bound(bag.begin(), bag.end(), jewerly[i].first) != bag.end() //failed

我已经用clock()检查了它,它明显慢于另一个。

这两个代码之间的区别是什么?


#include <cstdio>
#include <set>
#include <algorithm>
using namespace std;

const int MAXN = 300100;

bool cmp(pair<int, int> a, pair<int, int> b)
{
    if(a.second != b.second)
        return a.second > b.second;
    return a.first < b.first;
}

pair<int, int> jewerly[MAXN];
multiset<int> bag;

int main()
{
    int N, K, M;
    scanf("%d%d", &N, &K);

    int w, p;
    for(int i = 0; i<N; i++)
    {
        scanf("%d%d", &w, &p);
        jewerly[i] = {w, p};
    }

    for(int i = 0; i<K; i++)
    {
        scanf("%d", &M);
        bag.insert(M);
    }

    sort(jewerly, jewerly+N, cmp);

    clock_t begin = clock();

    long long sum = 0;
    for(int i = 0; i<N; i++)    // #1
    {
        if( bag.empty() ) break;
        if( lower_bound(bag.begin(), bag.end(), jewerly[i].first) != bag.end())
        {
            sum += jewerly[i].second;
            bag.erase(bag.lower_bound(jewerly[i].first));
        }
    }

    /*
    for(int i = 0; i<N; i++)   //#2
    {
        if( bag.empty() ) break;
        if( bag.lower_bound(jewerly[i].first) != bag.end())
        {
            sum += jewerly[i].second;
            bag.erase(bag.lower_bound(jewerly[i].first));
        }
    }
    */

    clock_t end = clock();    
    printf("%lf\n", double(end-begin));
}



  

测试输入       10 8       1 65       5 23       1 30       9 40       3 50       2 90       5 30       5 30       7 80       2 99       10       15       12       五       3       五       2       2

1 个答案:

答案 0 :(得分:3)

std::lower_bound无法访问std::multiset的内部结构。它不是O(log N),因为std::multiset的迭代器不是随机访问的(并且你不能在Theta(N)中更快地实现它而不是随机访问迭代器)

std::multiset::lower_bound可以访问树的结构,并且可以很容易地实现复杂度O(树高),即O(log N)