为什么两个看似 lower_bound() 相同的方法处理时间不同
Why two seemingly lower_bound() same method has different processing time
当我解决一道算法题时,我的解决方案由于时间问题无法通过。
但我意识到通过的和我的唯一区别是
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));
}
Test Input
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
5
3
5
2
2
std::lower_bound
无法访问 std::multiset
的内部结构。它不是 O(log N) 因为 std::multiset
的迭代器不是 random-access(而且你不可能实现它,因为 not random-access 迭代器比 Theta(N) 更快)
std::multiset::lower_bound
确实可以访问树的结构,并且可以很容易地以复杂度 O(tree height) 实现,即 O(log N)
当我解决一道算法题时,我的解决方案由于时间问题无法通过。
但我意识到通过的和我的唯一区别是
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));
}
Test Input 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 5 3 5 2 2
std::lower_bound
无法访问 std::multiset
的内部结构。它不是 O(log N) 因为 std::multiset
的迭代器不是 random-access(而且你不可能实现它,因为 not random-access 迭代器比 Theta(N) 更快)
std::multiset::lower_bound
确实可以访问树的结构,并且可以很容易地以复杂度 O(tree height) 实现,即 O(log N)