我正在处理LeetCode(Here)上的问题。当我完成问题时,我提出了:
class MovingAverage {
std::deque<int> numsToAverage;
int maxSize;
int currentTotal;
public:
/** Initialize your data structure here. */
MovingAverage(int size) {
maxSize = size;
currentTotal = 0;
}
double next(int val)
{
currentTotal += val;
numsToAverage.push_back(val);
if (numsToAverage.size() > maxSize)
{
currentTotal -= numsToAverage[0];
numsToAverage.pop_front();
}
return (double)currentTotal / (double)numsToAverage.size();
}
};
之后,我看到另一个解决方案与我的非常相似但是使用了队列。出于好奇,我只将交换到队列,然后我从第18百分位(deque)跳到第56百分位(队列)。这是队列代码:
class MovingAverage {
std::queue<int> numsToAverage;
int maxSize;
int currentTotal;
public:
/** Initialize your data structure here. */
MovingAverage(int size) {
maxSize = size;
currentTotal = 0;
}
double next(int val)
{
currentTotal += val;
numsToAverage.push(val);
if (numsToAverage.size() > maxSize)
{
currentTotal -= numsToAverage.front();
numsToAverage.pop();
}
return (double)currentTotal / (double)numsToAverage.size();
}
};
我的问题是为什么?我检查了std::queue,它默认为双端队列!为什么它会更快,因为它是一个队列?我唯一的猜测是,它将某些值缓存在哪里?但与此同时,一个队列,默认情况下是一个deque!插入/删除时间字面上不可能更好!
(旁注,我不考虑大小== 0的情况,因为问题没有测试它。实际上,如果你把它的代码猛烈粉碎他们的代码0)
答案 0 :(得分:0)
这是有根据的猜测:
内存控制器具有预取的“惯用性”,该奖励会奖励连续的,升序的内存访问,但对于降序访问则较慢。
相应地,用作FIFO容器的双端队列在推入一侧并弹出另一侧时具有首选方向。
就像,您的双端队列代码使用了最不受欢迎的方向。但是队列实现已经过优化,可以在其最喜欢的方向上使用底层双端队列。
有一个简单的方法可以验证这个假设(假设这些是非保证的实现细节)。在双端队列代码中,切换push_back --> push_front
和pop_front --> pop_back
。如果假设正确,则双端队列代码的速度应与队列实现一样快:-)