思路1:快排
考慮先使用快排實現,練習快排。
時間複雜度o(n):如果我們把每次分割槽遍歷的元素個數加起來,就是:n+n/2+n/4+n/8+…+1。這是乙個等比數列求和,最後的和等於 2n-1。所以,時間複雜度就為 o(n)。
因為一次快排可以實現乙個數歸位,比較index和n-k的大小
如果index==n-k就找到了
空間複雜度 : o(1)
class
solution
:def
findkthlargest
(self, nums: list[
int]
, k:
int)
->
int:
defgetindex
(low,high)
:# 返回依次排序,首元素就位後的索引
key = nums[low]
while low
while low
>=key:
high-=
1 nums[low]
=nums[high]
while low
<=key:
low+=
1 nums[high]
= nums[low]
# 跳出迴圈時low和high相等,此時的low或high就是key的正確索引位置
優化:雖然時間複雜度不高,但是執行也太慢了。對比了官方解答,發現快很多。關鍵點在於每次不以索引0作為pivot,而是n-k。這樣能夠避免極端測試用例,通常能夠更快的找到答案。
class
solution
:def
findkthlargest
(self, nums: list[
int]
, k:
int)
->
int:
defgetindex
(low, high,pivot)
:# 修改
key = nums[pivot]
# 修改
nums[pivot]
= nums[low]
# 修改 需要把首元素先複製出來,否則會丟失
while low < high:
while low < high and nums[high]
>= key:
high -=
1 nums[low]
= nums[high]
while low < high and nums[low]
<= key:
low +=
1 nums[high]
= nums[low]
# 跳出迴圈時low和high相等,此時的low或high就是key的正確索引位置
nums[low]
= key
return low
n =len(nums)
low, high =
0, n -
1 index = getindex(low, high,0)
# 修改
while index != n - k:
if n - k < index:
high = index -
1else
: low = index +
1 index = getindex(low, high,n-k)
# 修改
思路2:
庫函式heapq.nlargest(k,nums)
時間複雜度o(nlogk)
class
solution
:def
findkthlargest
(self, nums: list[
int]
, k:
int)
->
int:
return heapq.nlargest(k,nums)[-
1]# 堆的前k個數,逆序排列,取末尾的最小值
思路3:手寫快排
參考 powcai-排序
class
solution
:def
findkthlargest
(self, nums: list[
int]
, k:
int)
->
int:
defadjust_maxheap
(idx,maxlen)
: left =
2*idx+
1# 左孩子
right =
2*idx+
2# 右孩子
new_max = idx # 新的最大值的索引初始值
if left
>nums[new_max]
: new_max = left
if right
>nums[new_max]
: new_max = right
if new_max !=idx:
# 如果新的最大值不是舊的最大值,即需要進行調整
nums[new_max]
,nums[idx]
= nums[idx]
,nums[new_max]
adjust_maxheap(new_max,maxlen)
# 那麼需要把新的做大值的樹進行繼續調整
# 建堆
n =len(nums)
for i in
range
(n//2-
1,-1
,-1)
:# 起點為倒數第乙個非葉子節點,終點是第乙個節點
adjust_maxheap(i,n)
# print(nums)
# 取數調整堆
for j in
range(1
,k):
# 迴圈k-1次調整,此時第k大的值在根位置
215 陣列中的第K個最大元素
題目 方法一 二 時間複雜度 o n logk 向大小為k的堆中新增元素的時間複雜度為o logk 我們將重複該操作n次 空間複雜度 o k 用於儲存k個堆元素 自己解答 速度太慢?有待提高 time 2019 10 9 下午01 04 file 陣列中第k大元素 215.py 在未排序的陣列中找到...
215 陣列中的第K個最大元素
在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。輸入 3,2,1,5,6,4 和 k 2 輸出 5 輸入 3,2,3,1,2,4,5,5,6 和 k 4 輸出 4 你可以假設 k 總是有效的,且 1 k 陣列的長度。思路和演...
215 陣列中的第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 首先明白一點,題目要求返回第n個最大的元...