簡體   English   中英

這個算法不會在O(m log n)中運行嗎?

[英]Wouldn't this algorithm run in O(m log n)?

我正在處理Glassdoor軟件工程師的面試問題

問題是

給定一百萬個數字的列表,您將如何以有效的方式從列表中找到前n個數字

這是作者從同一鏈接給出的解決方案

  1. 創建一個最小堆
  2. 取m個元素中的前n個並放入堆中(O(n))
  3. 對於每個(mn)剩余元素,如果它大於堆的find-min,則插入堆並刪除min。 (如果列表已排序,則最壞情況為O((mn)log n )。

最終結果是你可以在O(n)內存使用和最壞情況下的O((mn)logn)運行時執行此操作。

我同意作者的算法和作者對該算法的空間復雜性的評估。 我遇到的問題是作者對插入堆中的運行時和總體時間的分析

對於“取m個元素中的前n個並放置在堆中”的步驟,不會在O(nlogn)中運行嗎? 至少根據我的課堂筆記Heap Add ,插入將是O(logn) ,因為你要插入n個元素,整個步驟的運行時將是O(nlogn)

考慮到這一點,整個算法的整體運行時間不會是,使用Big Oh Addition的大量添加

O(nlogn + (m-n)logn) = O(mlogn)

使用該方法構建堆,是的,但是有一個O(n)算法用於將數組轉換為堆。 有關詳細信息,請參見http://en.wikipedia.org/wiki/Binary_heap#Building_a_heap

也就是說,這個問題存在O(m)時間,O(n)內存解決方案,由例如Guava的Ordering.leastOf 一個實現是

  • 創建一個大小為2n的緩沖區
  • 循環遍歷原始數組,向緩沖區添加元素
  • 只要緩沖區已滿,使用O(n)quickselect只保留緩沖區中最高的n個元素,並丟棄其余的元素。
  • 使用最后一個quickselect從緩沖區中提取最高n個元素

這需要O(m / n)個快速選擇,每個選擇O(n),總時間為O(m)。

對於“取m個元素中的前n個並放置在堆中”的步驟,不會在O(nlogn)中運行嗎?

不必要。 您可以從O(n) n元素創建堆。 請參閱此處了解如何實現這一目標。

所以你有O(n + (m - n)log n) = O((m - n)log n) = O(m log n) 只有當n被認為是常數時,最后一步才是正確的,否則你應該像作者那樣將它保持為m - n

后續問題:你能解決O(m)的整個問題嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM