1. 程式人生 > >python:無序陣列中尋找第K大的元素

python:無序陣列中尋找第K大的元素

題目:

所謂“第(前)k大數問題”指的是在長度為n(n>=k)的亂序陣列中S找出從大到小順序的第(前)k個數的問題。

解法1:堆排序

採用元素下沉法,維護一個k大小的最小堆,對於陣列中的每一個元素判斷與堆頂的大小,若堆頂較大,則不管,否則,彈出堆頂,將當前值插入到堆中,繼續調整最小堆。時間複雜度O(n * logk)注意:heap和array的關係;Find_heap_kth函式裡面range的索引範圍;

def heap_build(parent,heap):
    child = 2*parent+1
    while child<len(heap):
        if child+1<len(heap) and heap[child+1]<heap[child]:
            child = child+1
        if heap[parent]<= heap[child]:
            break
        heap[parent],heap[child] = heap[child],heap[parent]
        parent,child = child,2*child+1
    return heap
    
def Find_heap_kth(array,k):
    if k > len(array):
        return None
    heap = array[:k]
    for i in range(k,-1,-1):
        heap_build(i,heap)
    for j in range(k,len(array)):
        if array[j]>heap[0]:
            heap[0] = array[j]
            heap_build(0,heap)
    return heap[0]
        
            
print(Find_heap_kth([2,1,4,3,5,9,8,0,1,3,2,5],6)) 

解法2:插入排序

由於是要找 k 個最大的數,所以沒有必要對所有數進行完整的排序。每次只保留 k 個當前最大的數就可以,然後每次對新來的元素跟當前 k 個樹中最小的數比較,新元素大的話則插入到陣列中,否則跳過。迴圈結束後陣列中最小的數即是我們要找到第 k 大的數。 時間複雜度 (n-k)logk

注意:巢狀for迴圈裡面,比較的物件;以及range的範圍

def Find_Kth_max(array,k):
    for i in range(1,k):
        for j in range(i,0,-1):
            if array[j] > array[j-1]:
                array[j],array[j-1] = array[j-1],array[j]
            else:
                pass
    for i in range(k,len(array)):
        if array[i] > array[k-1]:
            array[k-1] = array[i]
            for j in range(k-1,0,-1):
                if array[j] > array[j-1]:
                    array[j],array[j-1] = array[j-1],array[j]
                else:
                    pass
    return array[k-1]
            
print(Find_Kth_max([2,1,4,3,5,9,8,0,1,3,2,5],3))  

附加 1 求中位數實際上是第k大數的特例。 2 如果需要找出N個數中最大的K個不同的浮點數呢?比如,含有10個浮點數的陣列(1.5,1.5,2.5,3.5,3.5,5,0,- 1.5,3.5)中最大的3個不同的浮點數是(5,3.5,2.5)。解答:上面的解法均適用 3 如果是找第k到第m(0<k<=m<=n)大的數呢?解答:如果把問題看做m-k+1個第k大問題,則前面解法均適用。