Algorithm 获取序列中的n个最小数

Algorithm 获取序列中的n个最小数,algorithm,clojure,Algorithm,Clojure,从序列中提取n个最小数字的最有效方法是什么 [ [1 2 3] [9 2 1] [2 3 4] [5 6 7] ] 我想从基于第一项的序列中选取2个最小的 [1 2 3] [2 3 4] 目前,我正在对整个列表进行排序,然后选择前n个项目,但这可能不是最有效的方式,这是一个大列表,我需要经常这样做。如前所述,您可以使用中值算法在线性时间内选择第k个最小元素,然后在线性时间内进行分区。这将为您提供O(n)中的k个最小元素。但是,元素将是未排序的,因此如果您希望对k个最小的元素进行排序,则需要另

从序列中提取n个最小数字的最有效方法是什么

[ [1 2 3] [9 2 1] [2 3 4] [5 6 7] ]
我想从基于第一项的序列中选取2个最小的

[1 2 3] [2 3 4]

目前,我正在对整个列表进行排序,然后选择前n个项目,但这可能不是最有效的方式,这是一个大列表,我需要经常这样做。

如前所述,您可以使用中值算法在线性时间内选择第k个最小元素,然后在线性时间内进行分区。这将为您提供O(n)中的k个最小元素。但是,元素将是未排序的,因此如果您希望对k个最小的元素进行排序,则需要另一个O(klogk)

一些重要的注意事项:

  • 首先,虽然复杂性是O(n),但不能保证小常数,而且您可能会发现最小的改进,特别是如果您的n相当小的话。有一些随机线性选择算法在更好的实际时间内运行(通常预期运行时间为O(n),最坏情况更糟,但它们的常数比确定性算法小)

  • 为什么不能按排序方式维护数组?这可能会更有效。您只需将每个元素插入到正确的位置,这将花费O(logn),但找到最小的k将是O(1)(或者,如果您必须重新构建数组,则为O(k))

  • 如果您不同意上面的说明,那么另一种方法是在每次这样的过程之后保持数组的排序,在数组末尾提供insert in O(1),然后在每次需要查找k个最小元素时执行“merge sort”。也就是说,您只对新的进行排序,然后在线性时间内将它们合并。这将花费O(mlogm+n),其中m是自上次排序以来添加的元素数


  • 第6.4章介绍了一种延迟排序算法。延迟排序的优点在于,它只需要做尽可能多的工作来查找前x个值。因此,如果x如果n很小,您可以创建第二个大小为n的列表,并对其进行排序,这样您就可以快速访问该列表中最大的列表; 反复检查大列表,检查每个列表是否小于小列表中最大的列表; 如果是,请将其插入小列表中。。。小列表已满,从前面最旧的列表中弹出


    如果n小于3或4,您可以对其进行暴力。如果n可以更大,则需要进行二进制搜索以找到每个元素的插入点。如果n可能非常大,则可能需要另一种机制。

    是否回答了您的问题?(至少部分)排序很繁重。有关于价值观的信息吗?ie第一项的范围等?@galchen没有关于范围的信息,我实际上使用用户提供的谓词对它们进行排序,因此从技术上讲,我不知道内容是什么。
    (defn sort-parts                                                                                                                                                                                                            
      [work f]                                                                                                                                                                                                                  
      (lazy-seq                                                                                                                                                                                                                 
       (loop [[part & parts] work]                                                                                                                                                                                              
         (if-let [[pivot & xs] (seq part)]                                                                                                                                                                                      
           (let [psmaller? (partial f pivot)]                                                                                                                                                                                   
             (recur (list* (filter psmaller? xs)                                                                                                                                                                                
                           pivot                                                                                                                                                                                                
                           (remove psmaller? xs)                                                                                                                                                                                
                           parts)))                                                                                                                                                                                             
           (when-let [[x & parts] parts]                                                                                                                                                                                        
             (cons x                                                                                                                                                                                                            
                   (sort-parts parts f)))))))                                                                                                                                                                                   
    
    (defn qsort [xs f] (sort-parts (list xs) f))                                                                                                                                                                                
    
    (defn cmp [[a _ _] [b _ _]] (> a b))                                                                                                                                                                                        
    
    (def a [[1 2 3] [9 2 1]  [2 3 4] [5 6 7]])                                                                                                                                                                                   
    
    (take 2 (qsort a cmp))