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

2022-08-11 19:51:30 字數 1475 閱讀 1108

在未排序的陣列中找到第 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大的數。

c++**如下:

1

class

solution

8int t = 0;9

while(k--)

13return

t;14

}15 };

使用大根堆會使用額外的空間,所以另一種方法是快速選擇法。快速選擇法和快速排序差不多原理,但區別在於它不用排好序,嗯,從名字就能知道。。。在有n個數字的陣列中,求第k大的數,等價於求第kk = n-k+1小的數字。比如說在陣列[1, 2]中,第2大的數,就是第1 (2-2+1)小的數。

然後就是利用快排的思想啦,隨機選取乙個數(我一般選取中間的數),讓這個數左邊的數都比它小,右邊的數都比它大,然後看看左邊區間的數總共有多少,如果左邊超過了或者剛好等於kk個數的話,那麼第kk小的數肯定是在左邊啦,那麼就在左邊的區間再遞迴尋找。否則,在右邊的區間遞迴尋找。超級簡單的吧^ ^

c++**如下:

1

class

solution

9int fast_select(vector& q, int l, int r, int

k)18

if(j - l + 1 >= k) return

fast_select(q, l, j, k);

19else

return fast_select(q, j+1, r, k-(j-l+1

));20

}21 };

其實呢,也可以直接求第k大的數的。只要把上面的**中,第14行的》變成<,第15行的《變成》哈哈。也就是說,我們把所有大於某數的放在左邊,所有小於某數的放在右邊。這樣左邊區間的數全部都大於右邊區間的數,如果左邊區間的個數大於等於k,說明第k大的數一定在左邊~否則在右邊。

c++**如下:

1

class

solution

9int fast_select(vector& q, int l, int r, int

k)18

if(j - l + 1 >= k) return

fast_select(q, l, j, k);

19else

return fast_select(q, j+1, r, k-(j-l+1

));20

}21 };

LeetCode 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 說明 你可以假設 k 總是有效的,且 1...

LeetCode 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 說明 你可以假設 k 總是有效的,且 1...

Leetcode215 陣列中的第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...