【问题标题】:Remove last n elements of vector<int> in O(1) complexity C++?在 O(1) 复杂度 C++ 中删除 vector<int> 的最后 n 个元素?
【发布时间】:2020-05-05 21:21:21
【问题描述】:

我想以恒定时间复杂度 O(1) 删除整数向量的最后 n 个元素。我认为这应该是可行的,因为只需要对结束指针进行一些算术运算。但是,擦除、调整大小和删除都具有 O(n) 复杂度。有什么功能可以用?

【问题讨论】:

  • @PaulSanders 它说它的复杂性是线性的
  • 我认为这仅适用于非原始类型,当需要调用 n 析构函数时。对于ints,不需要调用析构函数,它应该是 O(1)。
  • @PaulSanders 我明白了,我认为它适用于所有事情。你是否也知道从前面移除是否也是 O(1)?
  • 不,不是,因为向量必须向左移动一个位置,这是向量中剩余元素数量的线性复杂度。

标签: c++ time-complexity stdvector


【解决方案1】:

C++ 标准(我相信)说从 std::vector 末尾删除 k 项的成本必须具有 O(k) 的时间复杂度,但这是数量的上限完成的工作,而不是下限。

C++ 编译器在为std::vector&lt;int&gt;::erase 生成代码时,可以检查类型并意识到在删除ints 时不需要对每个元素进行任何工作;它可以调整std::vector 的逻辑大小并收工。事实上,it looks like g++, with optimization turned on, does just that。这里生成的程序集不涉及任何循环,只是改变了std::vector的大小。

如果您不想依赖编译器来执行此操作,另一种选择是存储您自己的单独大小变量,然后“假装”您已从 std::vector 中删除项目,从不使用它们再次。这需要时间 O(1)。

希望这会有所帮助!

【讨论】:

  • 感谢您的回复。从正面擦除也是这样吗?
  • 不,我不这么认为。这需要您将项目向下移动以填充空位,这不会花费 O(1) 的时间。
  • 对,我也是这么想的,但是我发现pop_front的复杂度是O(1),那么从前面删除是不是也是不变的呢?
  • 向量类型没有pop_front。你在看双端队列还是列表?
猜你喜欢
  • 1970-01-01
  • 2010-10-22
  • 1970-01-01
  • 2021-08-24
  • 1970-01-01
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 2015-05-25
相关资源
最近更新 更多