提交**
總結在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。
示例 1:
輸入: [3,2,1,5,6,4] 和 k = 2
輸出: 5
示例 2:
輸入: [3,2,3,1,2,4,5,5,6] 和 k = 4
輸出: 4
說明:你可以假設 k 總是有效的,且 1 ≤ k ≤ 陣列的長度。
題意理解
先將陣列降序,再找出符合題意的第 k 個最大元素。
直接利用sort()函式對陣列進行降序排序。
jdk預設是快速排序
快速排序原理
將一組無序資料a[1]、a[2]、……a[n]按公升序排列:
首先任取資料a[x]作為基準;
比較a[x]與其它資料並排序,使a[x]排在資料的第k位,並且使a[1] ~ a[k-1]中的每乙個資料 < a[x],a[k+1] ~ a[n]中的每乙個資料 > a[x];
然後採用分治的策略分別對a[1] ~ a[k-1] 和 a[k+1] ~ a[n]兩組資料進行快速排序。
目前最熟悉最先想到的排序方法,兩層迴圈遍歷,通過比較相鄰元素交換大小值位置。
堆積是乙個近似完全二叉樹的結構,並滿足性質:子結點的鍵值或索引總是小於(或者大於)它的父節點。
演算法描述
將初始待排序關鍵字序列(r1,r2….rn)構建成大頂堆,此堆為初始的無序區;
將堆頂元素r[1]與最後乙個元素r[n]交換,此時得到新的無序區(r1,r2,……rn-1)和新的有序區(rn),且滿足r[1,2…n-1]<=r[n];
由於交換後新的堆頂r[1]可能違反堆的性質,因此需要對當前無序區(r1,r2,……rn-1)調整為新堆,然後再次將r[1]與無序區最後乙個元素交換,得到新的無序區(r1,r2….rn-2)和新的有序區(rn-1,rn)。
不斷重複此過程直到有序區的元素個數為 n-1,則整個排序過程完成。
解題思路
取nums前k個元素建立大小為k的最小堆;
剩餘k+1到n個元素依次和堆頂比較,比堆頂大則替換當前堆頂,並維護最小堆;
最終最小堆裡是前k大的元素,堆頂為前k大的元素中最小的元素,即kth大的元素
1]超出時間限制
輸入陣列元素數量很多時耗時長。
class
solution
:def
findkthlargest
(self, nums: list[
int]
, k:
int)
->
int:
# 替換nums[i]後維護最小堆:自頂向下調整新元素位置,直至該值滿足(parent value < son value)
defshift
(i,k)
: flag=
0while
(i*2+1
)t=i
if nums[i]
>nums[
2*i+1]
:
t=2*i+1if
(i*2+2
)>nums[
2*i+2]
:
t=2*i+
2if t==i:
flag=
1else
: nums[i]
,nums[t]
=nums[t]
,nums[i]
i=t
#o(k):建立大小為k的最小堆, k/2-1是最後乙個非葉節點,因為shift是向下調整,所以倒序從最下面出發,不然(4 32 1)->(2 34 1)->(2 14 3)->(2 14 3) 結果不對
for i in
range
(k/2,-
1,-1
):shift(i,k)
#o((n-k)logk),剩餘元素依次比較替換
for i in
range
(k,len
(nums)):
if nums[0]
: nums[0]
=nums[i]
shift(
0,k)
return nums[0]
#
學習新的排序思想——堆排序,適合解決 top k 的問題。 陣列中的第k個最大元素
在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。示例 1 輸入 3,2,1,5,6,4 和 k 2 輸出 5 示例 2 輸入 3,2,3,1,2,4,5,5,6 和 k 4 輸出 4 說明 你可以假設 k 總是有效的,且 1...
陣列中的第K個最大元素
題目 在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。法一 排序後輸出。法二 優先佇列 堆 法三 利用快速排序的方法。在這裡僅介紹法三,法一法二呼叫庫函式即可。思路 首先,找第k個最大的元素,即是找第n k 1個最小的元素。...
陣列中的第K個最大元素
在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。示例 1 輸入 3,2,1,5,6,4 和 k 2 輸出 5 示例 2 輸入 3,2,3,1,2,4,5,5,6 和 k 4 輸出 4 說明 你可以假設 k 總是有效的,且 1...