【发布时间】:2016-07-07 14:29:10
【问题描述】:
在下面的代码中,虽然它适用于较小长度的向量,但我正在为更大的向量长度超时。
long priceCalculate(vector < int > a, long k) {
long price = 0;
priority_queue<int>pq(a.begin(),a.end());
while(--k>=0){
int x = pq.top();
price = price + x;
pq.pop();
pq.push(x-1);
}
return price;
}
我有一个数字数组。我必须将最大数字添加到价格,然后将该数字减 1。再次找到最大数字,依此类推。我必须重复这个过程 k 次。 有没有比时间复杂度更低的优先队列更好的数据结构?
下面是使用向量排序的代码:
struct mclass {
public: bool operator()(int x, int y) {
return (x > y);
}
}
compare;
long priceCalculate(vector < int > a, long k) {
long price = 0;
sort(a.begin(), a.end(), compare);
while (--k >= 0) {
if (a[0] > 0) {
price = price + a[0];
a[0] = a[0] - 1;
sort(a.begin(), a.end(), compare);
}
}
return price;
}
但这也会在大输入长度时超时。
【问题讨论】:
-
你到底想做什么?
-
我不太明白你的代码在做什么。你有这堆元素,取出顶部,将其添加到
price,将其递减并重新插入队列,然后重复此操作k-1次。你知道k在一般情况下相对于a有多大吗?如果k和a一样大,您可以对向量进行排序并避免使用优先级队列(因为弹出 n 个元素需要 O(n log n) 时间)。 -
用代码逻辑编辑了问题。
-
您不需要将递减的数字重新插入队列中。这是算法的草图。弹出顶部的数字。继续递减并添加它,直到它等于新的顶部(在此之前,它显然仍然是最大的)。弹出另一个元素。继续递减并添加它两次,直到它等于新的顶部(这模拟了两个元素轮流成为最大的)。弹出第三个元素,继续递减并添加它三次。以此类推。
-
进一步的改进可以通过观察“不断递减和增加”部分相当于计算等差数列的和,可以用封闭形式表示。
标签: c++ data-structures time-complexity priority-queue