【发布时间】:2020-11-04 13:28:59
【问题描述】:
考虑一个排序的数字列表A = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},其中一个元素将在每一步中消除。
假设,我删除 A[4] 项目,我们有 A = {0, 1, 2, 3, 5, 6, 7, 8, 9}。
然后我再次删除A[4] 项目,我们有A = {0, 1, 2, 3, 6, 7, 8, 9}
然后A[7] 项目,我们有A = {0, 1, 2, 3, 6, 7, 8}
然后A[0]项目,我们有A = {1, 2, 3, 6, 7, 8}等等。
假设我们事先知道每个 kth 数组中要删除的元素的索引,即 [4, 4, 7, 0...]。此外,注意kth 数组的索引是如何在https://cs.stackexchange.com/q/128352/755 计算的。
如果我要在 C++ 中实现它并且A 是std::vector,我需要每次调用A.erase(A.begin()+k),我们将有一个在O(n^2) 中运行的算法。我什至不能在这里使用std::remove,因为元素不会重复。
这里最有效的方法是什么?
还有,是否可以最终打印出按顺序提取的数字序列?
【问题讨论】:
-
反转要删除的索引的顺序添加到它们:7 + 2、4 + 1、4 + 0,所以你得到9、5、4。如果你希望得到的序列是排序后,按该顺序在每个索引上使用
vector::erase。如果不需要对结果进行排序,则将每个索引(9、5、4)与vector::back()和resize(size()-1)交换。 -
您可以使用 remove_if 函数。它具有大约 O(n) 的复杂度。您可以从这里找到 API cplusplus.com/reference/algorithm/remove_if
-
@TedLyngmo,我不确定我是否理解你的方法。无论如何,您似乎都在使用 vector::erase,如果我要在 4、4、7 之后删除元素 0,我最终会删除 A[0+3] 而不是 A[0]。
-
@Ganesh 解决您的问题
print sequence of removed numbers from arrray总复杂度将是O(n log n) -
@Ganesh 好的,是的,“是否可以在不删除的情况下找出元素 pk 的索引...”在你的问题中确实有可能,正如我所展示的更多。可以对索引应用一些类似冒泡排序的算法,以降序重新计算它们,以便能够最大限度地减少对
erase的调用,并且必须移动尽可能少的数据。
标签: arrays algorithm c++11 vector stl