如何查找数字列表的前3个最小值

时间:2016-04-29 12:21:38

标签: list loops for-loop numbers min

我想知道如何在数字列表中找到前3或4个最小数字而不对列表进行排序而不删除元素。我在下面找到了一些代码可以很好地找到前2个最小的数字(分钟):

def second_smallest(numbers):
    m1, m2 = float('inf'), float('inf')
    for x in numbers:
        if x <= m1:
            m1, m2 = x, m1
        elif x < m2:
            m2 = x
    return m2
但是,我很难修改代码,给我第三个最小或第四个最小的数字。以下是我修改后的代码,有时似乎有效,但不是所有时间:

m1, m2, m3= float('inf'), float('inf'), float('inf')
    for x in min_of_summed_vals:
        if x < m1:
            m1, m2 = x, m1
        elif x < m2:
            m2 = x
        elif x > m2 and x < m3:
            m3 = x

有什么建议吗?

2 个答案:

答案 0 :(得分:0)

您可以使用此算法在最坏情况线性时间的未排序元素数组中查找第k个最大值/最小值:

  

kthSmallest(arr [0..n-1],k)

     

1)将arr []分为⌈n/ 5rceil;组   其中每组的大小为5,除了最后一组   可能少于5个元素。

     

2)对上面创建的⌈n/5⌉组进行排序,找到所有的中位数   组。创建一个辅助数组'median []'并存储中值   这个中位数数组中的所有⌈n/5⌉组。

     

//递归调用此方法查找中位数[0..⌈n/5⌉-1] 的中位数   3)medOfMed = kthSmallest(中位数[0..⌈n/5⌉-1],⌈n/10⌉)

     

4)围绕medOfMed分区arr []并获得其位置。        pos = partition(arr,n,medOfMed)

     

5)如果pos == k则返回medOfMed 6)如果pos&lt; k回归   kthSmallest(arr [l..pos-1],k)7)如果poa&gt; k回归   kthSmallest(arr [pos + 1..r],k-pos + l-1)

Here你可以找到一个完整的解释(最坏情况下的线性时间证明)和C ++实现

答案 1 :(得分:0)

def third_smallest(numbers):
    m1, m2, m3 = float('inf'), float('inf'), float('inf')
    for x in numbers:
        if x <= m1:
            m1, m2, m3 = x, m1, m2
        elif x < m2:
            m2, m3 = x, m2
        elif x < m3:
            m3 = x
    return m3

这应该适用于第三小的。您可以为第四小的应用类似的逻辑。实际上,列表m1,m2,m3是一个排序列表,如果x落在边界内,则迭代遍历此列表中x的每个元素。

要将此逻辑扩展到第n个元素,您可以使用插入排序逻辑将x插入m1.m2.m3..m n 列表。