簡體   English   中英

查找范圍內元素數量的最快方法

[英]Fastest way to find number of elements in a range

給定一個包含n elements的數組,如何在給定范圍index i to index j找到greaterequal給定value (x)的元素數量,以O(log n) index i to index jbetter復雜度?

我的實現是這個,但它是O(n)

for(a=i;a<=j;a++)
    if(p[a]>=x) // p[] is array containing n elements
    count++;

如果數組已排序,您可以使用二進制搜索找到小於X的第一個值,並且大於X的元素數是該元素之后的項數。 那將是O(log(n))。

如果數組未排序,則無法在少於O(n)的時間內完成此操作,因為您必須檢查每個元素以檢查它是否大於或等於X.

如果允許預處理數組,那么使用O(n log n)預處理時間,我們可以在O(log n)時間內回答任何[i,j]查詢。

兩個想法:

1)觀察到能夠回答[0,i][0,j]查詢就足夠了。

2)使用持久*平衡順序統計二進制樹,它維護樹的n個版本,版本i由版本i-1通過向其添加[i]而形成。 要回答query([0,i], x) ,可以在版本i樹中查詢元素數> x (基本上是排名信息)。 訂單統計樹可以讓您這樣做。

*: 持久數據結構是用於不可變數據結構的優雅函數編程概念,並且具有用於其構造的有效算法。

O(log N)中不可能因為你必須檢查所有元素,所以需要O(N)方法。

此標准算法基於quicksort的分區,有時稱為快速選擇

這個想法是你不對數組進行排序,而只是對包含x的部分進行分區,並在x是你的pivot元素時停止。 完成該過程后,您將x的所有元素設置為x和更大。 這與找到第k個最大元素時的過程相同。

閱讀有關如何在O(n)中找到長度為n的未排序數組中第k個最大元素的非常類似的問題

需求索引i到j不是引入問題復雜性的限制。

根據您的要求,數據未提前排序並且不斷在查詢之間進行更改,O(n)是您希望實現的最佳復雜性,因為無法在不查看的情況下計算大於或等於某個值的元素數量在他們所有人。

如果你仔細想想它就相當簡單:如果你不知道它是如何預先表示/訂購的,你就不能避免檢查任何類型搜索范圍的每個元素。

你可以構建一個平衡的二叉樹,甚至是動態的基數排序,但你只是將其他地方的開銷推到相同的線性或更差的線性O(NLogN)復雜度,因為這樣的算法再一次讓你檢查范圍內的每個元素首先要對它進行排序。

所以O(N)實際上並沒有錯。 這是理想的,您正在考慮改變外部數據的整體性質,以便提前對其進行有效排序或微觀優化(例如:並行處理具有多個線程的子范圍,前提是它們“足夠厚實”來調整它。

在您的情況下,您的要求似乎很嚴格,因此后者似乎是在分析器的幫助下最好的選擇。

暫無
暫無

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

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