題意描述:
在未排序的數組中找到第 k 個最大的元素。請注意,你需要找的是數組排序後的第 k 個最大的元素,而不是第 k 個不同的元素。
說明:
你可以假設 k 總是有效的,且 1 ≤ k ≤ 數組的長度。
示例:
示例一:
輸入: [3,2,1,5,6,4] 和 k = 2
輸出: 5
示例二:
輸入: [3,2,3,1,2,4,5,5,6] 和 k = 4
輸出: 4
解題思路:
Alice: 這題倒是有點意思了。
Bob: 怎麼說,很難嗎?
Alice: 不是很難,但是會有很多種做法。尋找一個未排序數組中的第 K 大的元素。可以直接排個序然後返回指定的值。這種最快也要O(n * log n)
。
Bob: 也可以維護一個最大堆
,先把所有元素都放進去,然後從堆頂取出 K
個元素,最後一個取出的就是第 K
大的元素。
Alice: 最大堆會比直接排序更快嗎 ?
Bob: 額,應該不會。不過也是一種解法了。
Alice: 還有一種,把冒泡排序
用進來。還記得嗎,冒泡排序可以每趟將一個最大或者最小的元素冒到 數組的末尾, 我們只要重複 K
趟就能在 length-K
的位置找到 第 K
大的元素了。
Bob: 喲,不錯不錯😎😎。
代碼:
Python 方法一: 排序 + 返回指定位置元素
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
nums.sort()
return nums[-k]
Java 方法一: 排序 + 返回指定位置的元素
class Solution {
public int findKthLargest(int[] nums, int k) {
Arrays.sort(nums);
//System.out.println(nums[0]);
return nums[nums.length-k];
}
}
Python 方法二:冒泡排序 => 超時
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
for x in range(k):
for z in range(0, len(nums)-1):
if nums[z] > nums[z+1]:
nums[z], nums[z+1] = nums[z+1], nums[z]
return nums[-k]
Java 方法二: 冒泡排序,順利通過。
class Solution {
public int findKthLargest(int[] nums, int k) {
int tmp = 0;
for(int i=0; i<k; ++i){
for(int j=0; j<nums.length-1; ++j){
if(nums[j] > nums[j+1]){
tmp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = tmp;
}
}
}
return nums[nums.length - k];
}
}
Python 方法三: 使用 heapq
模塊構建最大堆。
import heapq
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
# heapq.nlargest()方法返回列表中最大的若干個數組成的子列表。
# 其有兩個參數,k 爲最大的前k個數,nums 爲傳入的列表。
return heapq.nlargest(k, nums)[-1]
Java 方法三: 使用優先隊列 PriorityQueue
實現大頂堆。
class Solution {
public int findKthLargest(int[] nums, int k) {
PriorityQueue <Integer> maxHeap = new PriorityQueue<Integer>(new Comparator<Integer>(){
public int compare(Integer a, Integer b){
return a-b;
}
});
for(int num: nums){
maxHeap.add(num);
}
while(maxHeap.size() > k){
maxHeap.poll();
}
return maxHeap.poll();
}
}
易錯點:
- 一些測試點:
[3,2,1,5,6,4]
2
[3,2,3,1,2,4,5,5,6]
4
[1,0,2]
1
[1]
1
- 答案:
5
4
2
1
總結: