215 陣列中的第K個最大元素

2021-10-02 20:02:22 字數 3959 閱讀 6496

思路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個最大的元...