python:無序陣列中尋找第K大的元素
阿新 • • 發佈:2018-12-13
題目:
所謂“第(前)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大問題,則前面解法均適用。