[英]What is the time complexity of std::deque::erase function?
在這里,它說明了時間的復雜性:
線性刪除的元素數(破壞)。 另外, 取決於特定的庫實現 ,在位置與雙端隊列的兩端之間的元素數量上,最多需要額外的線性時間。
從第一句話我知道,如果要刪除雙端隊列中的任何數字,則最壞情況下的復雜度將為O(1)。
現在第二句話使我感到困惑。 取決於特定的庫實現是什么意思? 我正在使用STL庫,該庫與GCC編譯器一起提供。 在我的情況下,如何學習此函數的正確時間復雜度?
我需要將其設置為O(1),因為我正在運行O(n)擦除調用,如果std::deque::erase
為O(n),我的算法將具有二次復雜度,這是我不想要的。
如果必須從雙端隊列中刪除n
項目,通常需要使用remove/erase
習慣用法。
您從std::remove
開始刪除n
項本身。 這基本上將您的集合分為兩部分:一開始是您沒有刪除的部分,另一部分是您不再關心的內容。
它返回一個指向這兩個邊界的迭代器。 然后,您可以從那里擦除到結尾(一次),以擺脫不再關心的項目。
std::remove
基本上執行了我認為的“波紋復制”操作-從頭到尾遍歷整個集合,當找到要刪除的項目時,它會找到要保留的下一個項目,並且將其復制到要刪除的文件1 。
如果您不需要維護所保存物品的順序,則通常可以進一步提高速度。 從集合的開頭開始,找到您要刪除的項目(即,您當前要erase
)。 從年底開始找到你想要保存項目(即,一個你不會 erase
)。 交換這兩個項目,然后繼續“向內”搜索,直到兩個位置相遇。 現在,您要刪除的所有項目都在集合的末尾。 您可以在O(1)中刪除所有它們。
從理論上講,這兩者的總體復雜度是相同的-均為O(N)。 但是,在許多情況下,復制項目是相對昂貴的(相對於僅確定是否保留該項目)。 這樣可以最大程度地減少要復制/移動的項目的數量,因此,當復制/移動的成本很高時,可以節省大量時間(盡管,如前所述,如果其余對象的順序很重要,則不合適)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.