在 O(1) 复杂度 C++ 中删除 vector<int> 的最后 n 个元素?

Posted

技术标签:

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

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

【问题讨论】:

std::vector::resize()? en.cppreference.com/w/cpp/container/vector/resize @PaulSanders 它说它的复杂性是线性的 我认为这仅适用于非原始类型,当需要调用 n 析构函数时。对于ints,不需要调用析构函数,它应该是 O(1)。 @PaulSanders 我明白了,我认为它适用于所有事情。你是否也知道从前面移除是否也是 O(1)? 不,不是,因为向量必须向左移动一个位置,这是向量中剩余元素数量的线性复杂度。 【参考方案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。你在看双端队列还是列表?

以上是关于在 O(1) 复杂度 C++ 中删除 vector<int> 的最后 n 个元素?的主要内容,如果未能解决你的问题,请参考以下文章

C++中 std::sort 时间复杂度是多少? 是用来sort vector的

hdu 4841 用stl::vector解决约瑟夫问题

LeetCode 380 O时间插入删除和获取随机元素[Map 数组] HERODING的LeetCode之路

vector和list

C++中vector的at函数是怎么使用啊 ?代表啥值啊??

STL - STL容器的适用情况